反射:能够分析类能力的程序
反射的作用:
(1)在运行中分析类的能力
(2)在运行中查看对象,例如,编写一个toString方法供所有类使用
(3)实现通用的数组操作代码
(4)利用Method对象,这个对象很像C++中的函数指针
Class类
java运行时系统始终为所有的对象维护一个被称为运行时的类型标识,这个信息跟踪每个对象所属的类,虚拟机就利用运行时类型信息去选择相应的方法。
而这些信息就保存在Class类中
可以去用Object的getClass方法得到一个Class类型的实例
获取类名的三种方法
(1)使用相应的对象
Employee e;
Class c1 = e.getClass();
(2)调用静态方法名
String className = “java.util.Date”;
Class c1 = Class.forName(className);
(3)T.class将代表匹配的类对象
Class cl1 = Date.class;
Class cl2 = int.class;
Class cl3 = Doible[].class;
一个Class对象实际上表示的是一个类型,而这个类型未必一定是一种类。
int不是类,但是int.class是一个Class类型的对象
方法newInstance()
e.getClass().newInstance();
快速地创建一个类的实例
反射机制最重要的内容–检查类的结构
Field:描述类的域(成员变量)
Method:描述类的方法(成员函数)
Constructor:描述类的构造器
关于他们的函数:
getFields,getMethods,getConstructors
分别返回类提供的public域,方法,和构造器数组
getDeclaredFields,getDeclaredMethods,getDeclaredConstructors
分别返回类中声明的全部域,方法,和构造器数组,其中包括私有和受保护成员,但不包括超类的成员。
与他们有关的函数
Field[] getFields()
Field[] getDeclaredFields()
Method[] getMethods()
Method[] getDeclareMethods()
Constructor[] getConstructors()
Constructor[] getDeclaredConstructors()
第一个返回包含各自对应公有的域,方法,构造器,包括从超类继承来的
第二个返回全部,但是不包括从公有继承来的
如果没有域,那么第一二个方法返回一个长度为0的数组。
Field f = c1.getDeclaredField(“name”);
如果你想要访问私有成员那你就要给他相应的权限那么就应该这样做
f.setAccessible(true);
调用任意方法
在Method类中有一个invoke方法,它允许调用包装在当前Method对象中的方法
Object invoke(Object obj,Object… args)
最好使用接口和内部类
用法(不完整)
Class c = Class.forName("com.example.test1.ArrayList");
Constructor[] cons = c.getConstructors();
for(Constructor con : cons){
System.out.println(con);
}
//通过反射调用构造函数生成类对象
//默认构造
ArrayList list1 = (ArrayList) c.newInstance();
//调用带有参数的构造函数
Constructor con = c.getConstructor(int.class);
ArrayList list2 = (ArrayList) con.newInstance(200);
System.out.println("----------------------------------------");
Field[] fields = c.getDeclaredFields();
for(Field f : fields){
System.out.println(f);
}
//通过反射调用类对象的成员变量
Field field1 = c.getDeclaredField("size");//获取名为size的成员变量
System.out.println(field1);
field1.setAccessible(true);
field1.setInt(list1, 12);
System.out.println(list1);
System.out.println("-----------------------------------------");
Method[] methods = c.getDeclaredMethods();
for(Method m : methods){
System.out.println(m);
}
//通过反射调用类对象的成员方法
Method method = c.getMethod("get", int.class);
int val = (Integer)method.invoke(list1, 2);
System.out.println(val);