Java的反射

在我们平时的开发中,我们肯定会遇到过spring框架。框架中我们几乎不需要手动去new对象。只需要通过一些简单的配置,spring就会把对象为我们创建好。这里就用到反射。下面我们详细的介绍一下Java中的反射。

什么是Java反射

Java的反射机制是指运行时获取类的状态属性,可以调用它的任意属性和方法。

反射的作用

  • 在运行时,构造任意一个类对象
  • 在运行时,判断一个类的完整结构,比如属性,方法,内部类,实现的接口
  • 在运行时,判断一个对象所属的类
  • 在运行时,调用任意对象的方法,获取属性
  • 在运行时,生成动态代理

关键的类

java.lang.Class: 类的对象,只有这个在lang包下

java.lang.reflect.Method: 方法的对象

java.lang.reflect.Field:属性的对象

java.lang.reflect.Constructor:构造函数的对象

反射对象的使用

  1. 首先这个是我们用来测试反射的pojo类
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;

/**
 * @description:
 * @author: Administrator
 * @time: 2022/8/20
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
    private String name;
    private String hobby;
    private int age;

    public User(String name){
        this.name = name;
    }

    private @NotNull String sayHello(){
        return "Hello";
    }

    protected String sayProtected(){
        return "protect";
    }
}

  1. 测试Class
import com.hardy.pojo.User;
import org.junit.Test;

/**
 * @description:
 * @author: Administrator
 * @time: 2022/8/20
 */
public class TestClass {

    //        获取class的方式
    @Test
    public void testGetClass() throws ClassNotFoundException {
//        方式一:使用类的属性
        Class<User> userClass = User.class;
        System.out.println(userClass);

//        方式二:使用运行时类的getClass方法获取
        User user = new User();
        Class<? extends User> aClass = user.getClass();
        System.out.println(aClass);


//        方式三:使用Class的forName静态方法
        Class forName = Class.forName("com.hardy.pojo.User");
        System.out.println(forName);

//       方式四:使用classloader加载
        ClassLoader classLoader = User.class.getClassLoader();
        Class classLoad = classLoader.loadClass("com.hardy.pojo.User");
        System.out.println(classLoad);

    }
}
  1. 测试Construct
import com.hardy.pojo.User;
import org.junit.Test;

import java.lang.reflect.Constructor;

/**
 * @description:
 * @author: Administrator
 * @time: 2022/8/20
 */
public class TestConstructor {

    @Test
    public void test1() throws Exception {
        Class<User> userClass = User.class;
        Constructor<User> constructor = userClass.getConstructor();
        User hardy = constructor.newInstance();
        System.out.println(hardy);
        System.out.println("***********************");
//        通过参数的个数和类型来确定使用的构造参数
        Constructor<User> userConstructor = userClass.getConstructor(String.class);
        User user = userConstructor.newInstance("hardy");
        System.out.println(user);
    }
}
  1. 测试普通方法
package com.hardy;

import com.hardy.pojo.User;
import org.junit.Test;

import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;

/**
 * @description:
 * @author: Administrator
 * @time: 2022/8/20
 */
public class MethodTest {

    @Test
    public void test1() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException, InstantiationException {
        Class<User> userClass = User.class;

        Constructor<User> constructor = userClass.getConstructor();
        User user = constructor.newInstance();
        // 获取所有public的方法, 不包含private/protected方法
        Method[] methods = userClass.getMethods();
        Arrays.stream(methods).forEach(System.out::println);
        System.out.println("*************************");
//        获取所有的方法,包括private/protect
        Method[] declaredMethods = userClass.getDeclaredMethods();
        Arrays.stream(declaredMethods).forEach(System.out::println);
        System.out.println("----------------------------");
        Method setName = userClass.getMethod("setName", String.class);
        setName.invoke(user, "myname");
        System.out.println(user);
        System.out.println("********************");
//        获取注解
        Method toString = userClass.getMethod("toString");
        Annotation[] annotations = toString.getAnnotations();
        Arrays.stream(annotations).forEach(System.out::println);

        String canonicalName = userClass.getCanonicalName();
        System.out.println(canonicalName);
//        调用私有方法
        Method sayHello = userClass.getDeclaredMethod("sayHello");
//        开启私有方法调用
        sayHello.setAccessible(true);
        sayHello.invoke(user);
    }
}
  1. 测试属性
package com.hardy;

import com.hardy.pojo.User;
import org.junit.Test;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;

/**
 * @description:
 * @author: Administrator
 * @time: 2022/8/20
 */
public class FieldTest {
    @Test
    public void test1() throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException, NoSuchFieldException {
        Class<User> userClass = User.class;
        Constructor<User> constructor = userClass.getConstructor();
        User user = constructor.newInstance();
        Field[] fields = userClass.getFields();
        Arrays.stream(fields).forEach(System.out::println);
        System.out.println("****************");
        Field[] declaredFields = userClass.getDeclaredFields();
        Arrays.stream(declaredFields).forEach(System.out::println);
        System.out.println("************");
        Field name = userClass.getDeclaredField("name");
        name.setAccessible(true);
//        获取属性的值
        Object o = name.get(user);
        System.out.println(o);
        System.out.println("-------------");
//       修改属性的值
        name.set(user, "Hardy");
        System.out.println(user);
    }
}
posted @   永和九年  阅读(65)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
点击右上角即可分享
微信分享提示