满嘴都是糖果

反射就是把Java类中的各个成分映射成一个个的Java对象,通常将反射与代理杰哥,构造新工具。

Java中主要由以下的类来实现Java反射机制

  1. Class类:代表一个类。
  2. Field类:代表类的成员变量(成员变量也称为类的属性)。
  3. Method类:代表类的方法。
  4. Constructor类:代表类的构造方法。

Class类

获取Class对象

1.Class.forName("全类名"),将字节码文件加载仅内存,获取Class对象。通过将forNamenewInstance配合使用,调用默认构造器初始化一个新的对象,如果该类没有默认构造器会抛出异常。但是目前newInstance方法已经是被JDK15标注为不推荐使用,它会在编译期跳过异常检查,推荐使用Constructor类中的newInstance()方法。

String s = "java.util.Random";
Object m = Class.forName(s).newInstance();

2.类名.class,通过类名的属性class获取Class对象

3.对象.getClass()getClass()方法定义于Object类中

public final native Class<?> getClass();

4.xxxClassLoader.loadClass()通过类加载器传入类路径获取

Class<?> loadClass(String name);

值得注意的是,类加载器获取Class对象仅仅为类加载过程中的加载阶段,因此没有涉及类的准备阶段和初始化阶段,因此类中的静态变量不会赋值(准备阶段),静态代码块和类构造器不会执行(初始化阶段)

Class对象内方法

获取成员变量

Field[] getFields(); //获取所有public成员变量
Field getField(String name); //获取指定字段名的public成员变量
Field[] getDeclaredFields(); //获取所有成员变量,不考虑是否为public
Field getDeclaredField(String name); //获取指定字段名的成员变量,不考虑是否为public

获取构造方法

Constructor<?>[] getConstructors();
Constructor<T> getConstructor(Class<?>... parameterTypes);
Constructor<?>[] getDeclaredConstructors();
Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes);

获取成员方法

Method[] getMethods();
Method getMethod(String name, Class<?>... parameterTypes);
Method[] getDeclaredMethods();
Method getDeclaredMethod(String name, Class<?>... parameterTypes);

获取全类名

String getName();

Field类

设置访问限制符

setAccessible(boolean flag);

设置值

set(Object obj, Object value);
set(Object obj, int value);
set(Object obj, char value);
...

获取值

Object get(Object obj);
int getInt(Object obj);
char getChar(Object obj);
...

Constructor类

设置访问限制符

setAccessible(boolean flag);

通过参数指定构造方法构造一个对象

public T newInstance(Object ... initargs);

Method类

设置访问限制符

setAccessible(boolean flag);

执行方法

public Object invoke(Object obj, Object... args);

这里把动态代理也贴一下

JDK动态代理使用:继承InvocationHandler接口,以及实现其中的invoke()方法

public interface SmsService {
    String send(String message);
}
public class SmsServiceImpl implements SmsService {
    public String send(String message) {
        System.out.println("send message:" + message);
        return message;
    }
}
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class DebugInvocationHandler implements InvocationHandler {
    /**
     * 代理类中的真实对象
     */
    private final Object target;

    public DebugInvocationHandler(Object target) {
        this.target = target;
    }


    public Object invoke(Object proxy, Method method, Object[] args) throws InvocationTargetException, IllegalAccessException {
        //调用方法之前,我们可以添加自己的操作
        System.out.println("before method " + method.getName());
        Object result = method.invoke(target, args);
        //调用方法之后,我们同样可以添加自己的操作
        System.out.println("after method " + method.getName());
        return result;
    }
}