java 反射

1.获取类基本信息


        String path = "com.been.Reflect";
        Class clazz1 = Class.forName(path);
        Class clazz2 = Class.forName(path);

        //Class 虚拟机把类加载到内存,Class是一种类型
        System.err.println(clazz1.hashCode() == clazz2.hashCode());

        //获取类信息
        System.err.println("完全限定类名:"+clazz1.getName());
        System.err.println("类名:"+clazz1.getSimpleName());

结果:
true
完全限定类名:com.been.Reflect
类名:Reflect 

2.获取属性(字段)基本信息


        //获取属性字段
        //getField | getFields 只能获取访问方式为public的属性
        System.err.println("获取public声明的属性"+clazz1.getFields().length);
        System.err.println("获取public声明的属性"+clazz1.getField("phone"));

        //getDeclaredFields | getDeclaredField 可以获取所有属性 不区分权限
        System.err.println("获取所有属性:"+clazz1.getDeclaredFields().length);
        System.err.println("获取所有属性:"+clazz1.getDeclaredField("name"));
        for (Field field :clazz1.getDeclaredFields()){
            System.err.println("属性:"+field);
        }

结果:
获取public声明的属性2
获取public声明的属性public java.lang.String com.been.Reflect.phone
获取所有属性:4
获取所有属性:private java.lang.String com.been.Reflect.name
属性:private java.lang.String com.been.Reflect.name
属性:private java.lang.Integer com.been.Reflect.age
属性:public java.lang.String com.been.Reflect.phone
属性:public java.util.Map com.been.Reflect.map

3.获取方法基本信息


        //获取方法的信息
        Method[] methods = clazz1.getDeclaredMethods();
        for (Method m : methods){
            System.err.println("方法:"+m+"--参数类型:"+ Arrays.toString(m.getParameterTypes()));
        }
        //第二个参数 是方法的参数类型,是一个可变参数
        System.err.println(clazz1.getDeclaredMethod("setAge",Integer.class));

结果:
方法:public java.lang.String com.been.Reflect.getName()--参数类型:[]
方法:public void com.been.Reflect.setName(java.lang.String)--参数类型:[class java.lang.String]
方法:public void com.been.Reflect.setAge(java.lang.Integer)--参数类型:[class java.lang.Integer]
方法:public java.lang.Integer com.been.Reflect.getAge()--参数类型:[]
public void com.been.Reflect.setAge(java.lang.Integer)

4.获取构造函数基本信息


        //获取构造器
        System.err.println("构造器:"+Arrays.toString(clazz1.getDeclaredConstructors()));
        System.err.println("构造器:"+clazz1.getDeclaredConstructor(String.class,Integer.class));

结果:
构造器:[public com.been.Reflect(), public com.been.Reflect(java.lang.String,java.lang.Integer)]
构造器:public com.been.Reflect(java.lang.String,java.lang.Integer)

5.反射创建对象


        //动态创建对象
        //无参创建对象
        Reflect reflect = (Reflect) clazz1.newInstance();
        //使用有参构造器创建对象
        Constructor c = clazz1.getDeclaredConstructor(String.class,Integer.class);
        Reflect reflect1 = c.newInstance("小米",12);
        System.err.println("reflect"+reflect+"  reflect1"+reflect1);

结果:
reflectcom.been.Reflect@6822ed4b  reflect1com.been.Reflect@4d090c56

6.通过反射调用方法


        //通过反射调用方法
        Method method = clazz1.getMethod("setName", String.class);
        method.invoke(reflect1,"qwertyu");
        System.err.println("reflect1 getName"+reflect1.getName());

结果:
reflect1 getNameqwertyu

7.通过反射操作属性


        //通过反射操作属性
        Field f = clazz1.getDeclaredField("name");
        //java.lang.IllegalAccessException: Class com.reflect.BaseReflect can not access a member of class com.been.Reflect with modifiers "private"
        f.setAccessible(true);  // 不需要安全检查  可以直接访问  同时设置为true 能提高反射的效率
        f.set(reflect1,"ppqqcc");
        System.err.println("reflect1 setPropt name"+reflect1.getName());
        System.err.println("reflect1 setPropt name"+f.get(reflect1));  //通过反射获取属性值

结果:
reflect1 setPropt nameppqqcc
reflect1 setPropt nameppqqcc

8.通过反射获取泛型类型


        //获取泛型类型    方法中带有 Generic  则与获取泛型有关
        Field field = clazz1.getField("map");
        System.err.println("获取属性类型:"+field.getType().getName());
        //获取反射类型  <String,Array>   ParameterizedType 反射类型实体类
        Type type = field.getGenericType();
        //判断
        if(type instanceof ParameterizedType){
            Type[] types = ((ParameterizedType)type).getActualTypeArguments();
            for (Type t:types) {
                System.err.println("泛型类型:"+t);
            }
        }

结果:
java.util.Map
泛型类型:class java.lang.String
泛型类型:interface java.sql.Array
总结:带Declared的都是访问所有的,如  getDeclaredField,带 Generic的与泛型有关。ParameterizedType 是一个字段是否带有泛型的类型。f.setAccessible(true):操作私有属性要关闭安全检查,关闭安全检查会提升反射的速度。

 

posted @ 2018-03-02 16:14  xiaofei001  阅读(94)  评论(0)    收藏  举报