Java反射总结

java中有三种类类加载器。
1)Bootstrap ClassLoader 此加载器采用c++编写,一般开发中很少见。
2)Extension ClassLoader 用来进行扩展类的加载,一般对应的是jre\lib\ext目录中的类
3)AppClassLoader 加载classpath指定的类,是最常用的加载器。同时也是java中默认的加载器。
getParent() 返回该类加载器的父类加载器。
loadClass(String name) 加载名称为 name 的类,返回的结果是 java.lang.Class 类的实例。
findClass(String name) 查找名称为 name 的类,返回的结果是 java.lang.Class 类的实例。
findLoadedClass(String name) 查找名称为 name 的已经被加载过的类,返回的结果是 java.lang.Class 类的实例。
defineClass(String name, byte[] b, int off, int len) 把字节数组 b 中的内容转换成 Java 类,返回的结果是 java.lang.Class 类的实例。这个方法被声明为 final 的。
resolveClass(Class<?> c) 链接指定的 Java 类。


获取当前线程的ClassLoader:

ClassLoader loader = Thread.currentThread().getContextClassLoader();
Class.getClassLoader() ;


实例化Class类对象的三种方式:
Class.forName("Reflect.Demo");
new Demo().getClass();
Demo.class;

Class.forName(className)实际上是调用Class.forName(className, true, this.getClass().getClassLoader())。注意第二个参数,是指Class被loading后是不是必须被初始化。

通过Class实例化其他类的对象
Class<?>  demo=Class.forName("Reflect.Person");
Constructor<?> cons[]=demo.getConstructors();
Object object = cons[0].newInstance(args);


通过Class实例化接口
Class<?> intes[]=demo.getInterfaces();


取得其他类中的父类
Class<?> superClass=demo.getSuperclass();


调用其他类中的方法
demo = Class.forName("Reflect.Demo");
Method method=demo.getMethod("toString");
method.invoke(demo.newInstance());

Method[] methods = demo.getDeclaredMethods(); 

通过反射操作属性:
Field field = demo.getDeclaredField("sex");
field.setAccessible(true);
field.set(obj, "男");

Field[] fields = Demo.class.getDeclaredFields(); //类中任何可见性的属性不包括基类
fields = Demo.class.getFields();  //只能获得public属性包括基类的   



使用数组
Class string = Class.forName("java.lang.String"); 
Object object= Array.newInstance(string, 10); 
Array.set(object, 5, "this is a test"); 
 String s = (String) Array.get(arr, 5);
 



=============================应用==========================
JDK动态代理:
与静态代理类对照的是动态代理类,动态代理类的字节码在程序运行时由Java反射机制动态生成,无需程序员手工编写它的源代码。动态代理类不仅简化了编程工作,而且提高了软件系统的可扩展性,因为Java 反射机制可以生成任意类型的动态代理类。java.lang.reflect 包中的Proxy类和InvocationHandler 接口提供了生成动态代理类的能力。
public class MyHandler implements InvocationHandler {  
    private Object target;  
      
    public Object bind(Object target) {  
        this.target = target;   
        return Proxy.newProxyInstance(target.getClass().getClassLoader(),  
                target.getClass().getInterfaces(), this);  
    }   
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {  
        System.out.println("事物开始");   
        Object result = method.invoke(target, args);  
        System.out.println("事物结束");  
        return result;  
    }    
  
}  




Cglib动态代理
JDK的动态代理机制只能代理实现了接口的类,而不能实现接口的类就不能实现JDK的动态代理,cglib是针对类来实现代理的,他的原理是对指定的目标类生成一个子类,并覆盖其中方法实现增强,但因为采用的是继承,所以不能对final修饰的类进行代理。

public class MyCglib implements MethodInterceptor {  
    private Object target;  
   
    public Object getInstance(Object target) {  
        this.target = target;  
        Enhancer enhancer = new Enhancer();  
        enhancer.setSuperclass(this.target.getClass());  
        // 回调方法  
        enhancer.setCallback(this);  
        // 创建代理对象  
        return enhancer.create();  
    }  
    @Override  
    // 回调方法  
    public Object intercept(Object obj, Method method, Object[] args,  
            MethodProxy proxy) throws Throwable {  
        System.out.println("事物开始");  
        proxy.invokeSuper(obj, args);  
        System.out.println("事物结束");  
        return null;  
    }  
}  

你可能感兴趣的:(java反射)