反射的基本知识及常用API
1、class类的反射
Java中万事万物皆对象。
每个类是java.lang.Class类的实例对象,
类的生成方法:
1、Class test1 = new Test().getClass();
2、Class test2 =Test.class;
test1、test2、test3表示Test类的类类型;
3、Class test3 = Class.forName(“包名+类名“);
注:
一个类只可能是Class一个实体对象。
可以通过类的类类型来创建该类的对象实例。
test1.newInstance();这是调用了Test本身的空构造函数。
2、属性的反射
通过Class得到类声明的属性。
Field field clazz.getField(fieldName);
通过对象得到该属性的实例,如果这个属性是非公有的,这里会报IllegalAccessException。
Field 成员变量
该类封装了关于成员变量的操作。
clazz.getFileds()获取的是所有的public的成员变量信息。
clazz.getDeclaredFieds获取的是该类自己声明的成员变量的信息。
Field的常用方法:
field.getName();
field.getType();
3、方法的反射
编译时候加载类为静态加载类,运行时加载类是动态加载类。
new 创建对象是静态加载类,在编译时刻就需要加载所有可能使用到的类;
通过动态加载类可以解决该问题。
在运行时,加载类
Class clazz = Class.forName(“com.test.test”);
通过类类型,创建该类对象
Animal a = (Anamile)clazz.newInstance();
使用Animal这个父类,来统一所有的动态加载的文件类。
Method
是方法对象。有方法相应的方法。
一个成员方法都是一个Method对象
getMethods()方法获取的是所有public的函数,包括从父类继承而来的方法
getDeclaredMethods()获取的是该类所有自己声明的方法,不访问父类方法
4、构造器函数的反射
clazz.getConstructors()获取所有的public的构造函数
clazz.getDeclaredConstructors得到所有的构造函数
java.long.Constructor中封装了构造函数的信息
5、url
Class.getResource(path)
path 若以“/”开头则表示,则绝对资源名是 ‘/’ 后面的 path 的一部分
否则,绝对路径是包名/path
6、方法的反射
如何获取某个方法
clazz.getMethod(“方法名称”,参数列表(可变参数));获取的是public方法
clazz.getDeclaredMethod(“方法名称”,参数列表(可变参数));获得是自己声明的方法
例:
clazz.getMethod(“test”,int.Class,int.Class);
clazz.getMethod(“test”,new Class[]{class,class});
方法的反射操作
method.invoke(对象,参数);在方法为静态方法时,对象可以为null
注:方法如果没有返回值返回null,有返回具体的返回值;
例
method.invoke(new TEST(),1,2);
或
method.invoke(new TEST(),new Object[]{1,2});
7、通过Class、Method来认识泛型本质
Arraylist list = new ArrayList();
Arraylist<String> list1 = new ArrayList<String>();
Class c1 = list.getClass();
Class c2 = list1.getClass();
此时c1等于c2
这说明编译之后集合的泛型是去泛型话的,Java中集合的泛型,是防止错误输入的,只在编译阶段有效,绕过编译就无效了。可以使用clazz添加值,来测试是否是正确的。
集合的泛型本身是编译前的,防止错误的。
注:
八大基本数据类型、void都有自己的Class模板,但是int和Integer这不是同一个class模板。