Java笔记--反射机制

时间:2022-09-20 08:43:47

1、Reflection(反射)是被视为动态语言的关键,反射机制允许程序在执行期借助于Reflection API取得任何类的内部信息,并能直接操作任意对象的内部属性及方法。

2、Java反射机制提供的功能:

--在运行时判断任意一个对象所属的类;

--在运行时构造任意一个类的对象;

--在运行时判断任意一个类所具有的成员变量和方法;

--在运行时调用任意一个对象的的成员变量和方法;

--生成动态代理。

3、java.lang.Class类:此类是反射的源头

--当创建一个类(.java)并通过编译生成字节码文件(.class)之后,使用java.exe命令加载这个字节码文件(.class),当其被加载内存以后,就是一个运行时类,存在在缓存区,这个运行时类本身就是一个Class类的实例;

--一个运行时类只加载一次;

4、使用Class类的实例可以进行的操作:1)创建对应的运行时类的对象;2)获取对应的运行时类的完整结构(属性、方法、所在包、异常等);3)调用对应的运行时类的指定的结构(属性、方法、构造器);

5、反射的应用:动态代理;

6、获取Class实例的方法:1)调用运行时类本身的.class属性;2)通过运行时类的对象获取(XX.getClass());3)通过Class的静态方法获取(Class.forName(className));4)通过类的加载器获取(ClassLoader classLoader = this.getClass().getClassLoader();classLoader.loadClass(className));

--类的加载器是用来把类装载进内存的。JVM规范定义了两种类型的类加载器:启动类加载器和用户自定义加载器。

7、newInstance()创建运行时类对象时要求:1)对应的运行时类要有空参构造器;2)构造的权限足够。

8、获取运行时类的完整性结构:1)获取属性:Field[] getFields();//获取本类及父类中权限public的属性;getDeclaredField();//获取本类中声明的所有属性

                2)获取属性的权限修饰符:int Field.getModifiers();//1:public 2:private 0:缺省

                3)获取属性的变量类型:Class Field.getType();

                4)获取属性名:String Field.getName();

                5)获取方法:Method[] getMethods();//获取本类及父类中权限public的方法;getDeclaredMethods();//获取本类中声明的所有方法

                6)获取方法的注解:Annotation[] Method.getAnnotation();

                7)获取方法的权限修饰符:int Method.getModofiers();

                8)获取方法的返回值类型:Class Method.getReturnType();

                9)获取方法的方法名:String[] Method.getNames();

                10)获取方法的形参列表:Class[] Method.getParameterTypes();

                11)获取方法的异常类型:Class[] Method.getExceptionTypes();

                12)获取所有构造器:Constructor[] getDeclaredConstructors();

                13)获取运行时类的父类:Class getSuperclass();//不包括泛型 Type getGenericSuperclass();//包括泛型

                14)获取父类的泛型:ParameterizedType param = (ParameterizedType)type; Type[] ars = param.getActualArguments();

                  15)获取实现的接口:Class[] getInterfaces();

                16)获取所在的包:Package getPackage();

                17)获取类注解:Annotation[] getAnnotations();

9、动态代理是指客户通过代理类来调用其他对象的方法,并且是在程序运行时根据需要动态创建目标类的代理对象。它的使用场合有调试和远程方法调用。

10、代理设计模式的原理:使用一个代理将对象包装起来,然后用该代理对象取代原始对象,任何对原始对象的调用都要通过代理,代理对象决定是否以何时将方法调用转到原始对象上。

--例:

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class TestProxy {


    public static void main(String[] args) {
        RealSubject real = new RealSubject();
        
        MyInvocationHandler handler = new MyInvocationHandler();
        
        //动态地返回一个实现了被代理对象所在类实现的的接口的代理类对象
        Subject sub = (Subject)handler.blind(real);
        sub.action();
    }

}
interface Subject{
    void action();
}
//被代理类
class RealSubject implements Subject{
    public void action(){
        System.out.println("Hello World!");
    }
}
//动态代理类
class MyInvocationHandler implements InvocationHandler{

    Object obj;
    public Object blind(Object obj){
        this.obj = obj;
        
        //创建一个代理类的实例并返回
        return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), this);
    }
    
    //当通过代理类的对象发起对呗重写的方法的调用时,都会转化为invoke方法的调用
    @Override
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
        return method.invoke(method, args);
    }
}