反射

2019-09-30  本文已影响0人  超级笔记本

1、获取类类型 Class

三种方法获取类类型

//1 静态变量class
Class class1 = User.class;
System.out.println(class1.getName());
//1 类对象的getClass方法
User user = new User();
Class c2 = user.getClass();
System.out.println(c2.getName());
//3 Class静态方法forName
Class class3 = Class.forName("com.my.java.User");;
System.out.println(class3.getName());

输出结果

com.my.java.User
com.my.java.User
com.my.java.User

1、成员变量 Field

1、getDeclaredField获取私有成员变量,需要setAccessible(true),否则报错IllegalAccessException
2、getField只能获取public的变量,如果知道私有变量,则报错NoSuchFieldException

 Field field1 = c2.getField("msg1");
Object msg1 = field1.get(o);
System.out.println("成员变量msg1:" + msg1);
Field field2 = c2.getDeclaredField("msg2");
field2.setAccessible(true);
Object msg2 = field2.get(o);
System.out.println("成员变量msg1:" + msg2);

获取所有的成员变量

        //所有的public成员变量,包括父类
        Field[] fields = c2.getFields();
        for (Field field : fields) {
            System.out.println(field.getName());
        }
        //所有的方法,不包括父类
        Field[] declaredFields = c2.getDeclaredFields();
        for (Field field : declaredFields) {
            System.out.println(field.getName());
        }

方法对应能力范围


20170727235210926.png

2、方法 Method

1、getDeclaredMethod调用私有方法时,需要添加setAccessible(true)方法,否则报错IllegalAccessException
2、invoke执行该方法,并传递参数类型,不传或传错类型报错IllegalAccessException
3、getMethod或者getDeclaredMethod传递多个参数类型时可以new Class[]{String.class, String.class}

Class class1 = User.class;
Object o = class1.newInstance();//获取对象
//获取所有public方法,包括父类,参数:方法名,方法参数类的类类型
Method fun1 = c2.getMethod("fun1", String.class, String.class);
fun1.invoke(o, "admin", "123456");
//获取所有的方法,不包括父类,参数:方法名,方法参数类的类类型
Method fun2 = c2.getDeclaredMethod("fun2", String.class);
fun2.setAccessible(true);
fun2.invoke(o,"输出一段内容");

获取所有的方法

//所有的public方法,包括父类
Method[] methods = c2.getMethods();
for (Method method : methods) {
    System.out.println(method.getName());
}
//所有的方法,不包括父类
Method[] declaredMethods = c2.getDeclaredMethods();
for (Method method : declaredMethods) {
     System.out.println(method.getName());
}

方法对应能力范围


20170727235237680.png

3、构造方法 Constructor

同 Field 和 Method 一样,同样存在

getConstructor()
getDeclaredConstructor()
getConstructors()
getDeclaredConstructor()

方法对应能力范围


20170727235303590.png

4、通过反射了解集合泛型的本质

这个学到了,第一次知道这个。Java中集合的泛型,是防止错误输入的,只在编译阶段有效,绕过编译到了运行期就无效了。

        List<String> list = new ArrayList<>();
        list.add("一个String元素");
        Class c = list.getClass();
        Method method = c.getMethod("add", Object.class);
        method.invoke(list, 20);
        System.out.println("list.size:" + list.size());

参考文章
反射进阶,编写反射代码值得注意的诸多细节
Java基础与提高干货系列——Java反射机制

上一篇下一篇

猜你喜欢

热点阅读