反射
Java让我们在运行时识别对象和类的信息,主要有2种方式:一种是传统的RTTI(running-time type infomation ),它假定我们在编译时已经知道了所有的类型信息;另一种是反射机制,它允许我们在运行时发现和使用类的信息。
反射机制允许程序在运行时取得任何一个已知名称的class的内部信息,包括包括其modifiers(修饰符),fields(属性),methods(方法)等,并可于运行时改变fields内容或调用methods。
Java动态代理可以在不改变被调用对象源码的前提下,在被调用方法前后增加自己的操作,极大地降低了模块之间的耦合性。
获取class的三种方法:
1、通过对象调用 getClass() 方法来获取,通常应用在:比如你传过来一个 Object类型的对象,而我不知道你具体是什么类,用这种方法 Person p1 = new Person(); Class c1 = p1.getClass(); 2、直接通过 类名.class 的方式得到,该方法最为安全可靠,程序性能更高这说明任何一个类都有一个隐含的静态成员变量 class
Class c2 = Person.class; 3、通过 Class 对象的 forName() 静态方法来获取,用的最多, 但可能抛出 ClassNotFoundException 异常 Class c3 = Class.forName("com.ys.reflex.Person");
通过反射创建对象:
1.通过默认构造函数创建对象:Class<?> t = Class.forName("cn.test.reflect.A"); t.newInstance();
2. 通过指定构造函数创建对象:Class<?> t = Class.forName("cn.test.reflect.A"); Constructor<?> cons[] = t.getConstructors(); A a = (A) cons[2].newInstance("aa","bb");
通过Class来获取成员变量,方法等
1.获得类完整的名字 String className = c2.getName(); System.out.println(className); //输出com.ys.reflex.Person 2.获得类的public类型的属性。 Field[] fields = c2.getFields(); for(Field field : fields){ System.out.println(field.getName());//age } 3.获得类的所有属性。包括私有的 Field [] allFields = c2.getDeclaredFields(); for(Field field : allFields){ System.out.println(field.getName());//name age }
通过反射获取父类的信息(私有信息)
public class Parent {
    public String publicField = "parent_publicField";
    protected String protectField = "parent_protectField";
    String defaultField = "parent_defaultField";
    private String privateField = "parent_privateField";
}
public class Son extends Parent {
 }
public class ReflectionTest {
    public void testGetParentField() throws Exception{
        Class c1 = Class.forName("com.ys.model.Son");
        //获取父类私有属性值
        System.out.println(getFieldValue(c1.newInstance(),"privateField"));
    }
    public static Field getDeclaredField(Object obj,String fieldName) {
        Field field = null;
        Class c = obj.getClass();
        for(; c != Object.class ; c = c.getSuperclass()){
            try {
                field = c.getDeclaredField(fieldName);
                 //只有变为true,才能通过反射访问私有变量
                field.setAccessible(true);
                return field;
            }catch (Exception e){
                //这里甚么都不要做!并且这里的异常必须这样写,不能抛出去。
                //如果这里的异常打印或者往外抛,则就不会执行c = c.getSuperclass(),最后就不会进入到父类中了
            }
        }
        return null;
    }
    public static Object getFieldValue(Object object,String fieldName) throws Exception{
        Field field = getDeclaredField(object,fieldName);
        return field.get(object);
    }
} 
java里面可以通过反射获得方法参数名字和类型。
通过反射调用类里面的方法:
本文来自博客园,作者:LeeJuly,转载请注明原文链接:https://www.cnblogs.com/peterleee/p/10099385.html
 
                    
                     
                    
                 
                    
                
 
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号