1)概念:
是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
2)功能:
1>在运行时判断任意一个对象所属的类;
2>在运行时构造任意一个类的对象;
3>在运行时判断任意一个类所具有的成员变量和方法;
4>在运行时调用任意一个对象的方法;
5>生成动态代理。
3)获得某个对象的具体属性:
Class ownerClass = owner.getClass():得到对象owner的Class。
Field field = ownerClass.getField(fieldName):通过Class得到类声明的属性。
Object property = field.get(owner):通过对象得到该属性的实例,如果这个属性是非公有的,这里会报IllegalAccessException。如果需要访问到对象的private属性,需要首先调用:AccesibleObject.setAccessible(Field名字,true);
如果说是获取Class的静态属性:则第三句换成Object property=field.get(Class名字),而不是用实例的名字。
4)执行某个对象的方法:
5)新建某对象的实例:
6)判断是否为某个class的实例:
7)Reflection与introspection
Reflection这个字的意思是“反射、映象、倒影”,用在Java身上指的是我们可以于运行时加载、探知、使用编译期间完全未知的classes。换句话说,Java程序可以加载一个运行时才得知名称的class,获悉其完整构造(但不包括methods定义),并生成其对象实体、或对其fields设值、或唤起其methods1。
通过一个对象获得完整的包名和类名
是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
2)功能:
1>在运行时判断任意一个对象所属的类;
2>在运行时构造任意一个类的对象;
3>在运行时判断任意一个类所具有的成员变量和方法;
4>在运行时调用任意一个对象的方法;
5>生成动态代理。
3)获得某个对象的具体属性:
Class ownerClass = owner.getClass():得到对象owner的Class。
Field field = ownerClass.getField(fieldName):通过Class得到类声明的属性。
Object property = field.get(owner):通过对象得到该属性的实例,如果这个属性是非公有的,这里会报IllegalAccessException。如果需要访问到对象的private属性,需要首先调用:AccesibleObject.setAccessible(Field名字,true);
如果说是获取Class的静态属性:则第三句换成Object property=field.get(Class名字),而不是用实例的名字。
4)执行某个对象的方法:
public Object invokeMethod(Object owner, String methodName, Object[] args) throws Exception {
Class ownerClass = owner.getClass();
Class[] argsClass = new Class[args.length];
for (int i = 0, j = args.length; i < j; i++) {
argsClass = args.getClass();
}
Method method = ownerClass.getMethod(methodName, argsClass);
return method.invoke(owner, args);
}
如果是执行某个类的静态方法:method.invoke(null, args);
5)新建某对象的实例:
public Object newInstance(String className, Object[] args) throws Exception {
Class newoneClass = Class.forName(className);
Class[] argsClass = new Class[args.length];
for (int i = 0, j = args.length; i < j; i++) {
argsClass = args.getClass();
}
Constructor cons = newoneClass.getConstructor(argsClass);
return cons.newInstance(args);
}
这里说的方法是执行带参数的构造函数来新建实例的方法。如果不需要参数,可以直接使用newoneClass.newInstance()来实现。
6)判断是否为某个class的实例:
public boolean isInstance(Object obj, Class cls) {
return cls.isInstance(obj);
}
7)Reflection与introspection
Reflection这个字的意思是“反射、映象、倒影”,用在Java身上指的是我们可以于运行时加载、探知、使用编译期间完全未知的classes。换句话说,Java程序可以加载一个运行时才得知名称的class,获悉其完整构造(但不包括methods定义),并生成其对象实体、或对其fields设值、或唤起其methods1。
这种“看透class”的能力(the ability of the program to examine itself)被称为introspection(内省、内观、反省)。Reflection和introspection是常被并提的两个术语。
以上部分参考:http://pengcqu.iteye.com/blog/486575
下面部分纯粹自己做练习。
结合例子讲解:
Class Demo implements interfaceOne, interfaceTwo{
private int age;
public Demo(){}
public Demo(String str){}
public Demo(String str, int x){}
public void testMethod(){...}
public void setAge(int age){...}
public int getAge(){...}
}
通过一个对象获得完整的包名和类名
Demo demo = new Demo();
demo.getClass().getName(); //包名+类型 etc:reflect.Demo
实例化Class类对象:推荐使用第一种
//第一种:通过Class.forName("包名+类名")
Class<?> demo1 = Class.forName("reflect.Demo");
//第二种:
Class<?> demo2 = new Demo().getClass();
//第三种:
Class<?> demo3 = Demo.class;
通过Class实例化其他类的对象
Class<?> dmeo = Class.forName("reflect.Demo");
Demo instance = demo.newInstance();
注意:通过Class.newInstance()时,前提是Demo类必须有无参构造函数,因为newInstance()会默认调用无参构造方法
通过Class调用其他类中的构造函数
Class<?> demo = Class.forName("reflect.Demo");
// 获得Demo.Class的所有构造方法
Constructor<?> cons[]=demo.getConstructors();
* 数组的顺序跟构造函数声明的顺序相反
* cons[0] : Demo(String, int)
* cons[1] : Demo(String)
* cons[2] : Demo()
Demo instance = null;
instance = (Demo) cons[0].newInstance("hello", 20);
instance = (Demo) cons[1].newInstance("hello");
instance = (Demo) cons[2].newInstance();<span style="font-family: 'Microsoft YaHei';font-size:12px; background-color: rgb(255, 255, 255);"> </span>
返回一个类实现的接口、继承的父类
Class<?> demo = Class.forName("reflect.Demo");
Class<?> [] interfaces = demo.getInterfaces();
// 获得指定下标的接口名
String interfaceName = interfaces[i].getName();
// 获得父类的名字
Class<?> superClass = demo.getSuperclass();
String superClassName = superClass.getName();
获取修饰符
Class<?> demo = Class.forName("reflect.Demo");
// 获得所有的构造方法
Constructor<?> cons[] = demo.getConstructors();
for (int i = 0; i < cons.length; i++) {
// 获得修饰符的值
int mod = cons[i].getModifiers();
// 将修饰符的值转变为String类型(etc: public, private....)
String modifier = Modifier.toString(mod);
// 获得参数类型
Class<?> paramTypes[] = cons[i].getParameterTypes();
for (int j = 0; j < paramTypes.length; j++) {
// 获得参数名
String paramName = paramTypes[j].getName();
}
}
获得类的所有方法
Class<?> demo = Class.forName("reflect.Demo");
Method[] methods = demo.getMethods();
for (int i = 0; i < methods.length; i++) {
// 获取修饰符
int mod = methods[i].getModifiers();
String modifier = Modifier.toString(mod);
// 获取返回值
Class<?> returnType = methods[i].getReturnType();
String returnTypeName = returnType.getName();
// 获取方法名
String methodName = methods[i].getName();
// 获取方法参数
Class<?> paramTypes[] = methods[i].getParameterTypes();
for (int j=0; j<paramTypes.length; j++){
String paramName = paramTypes[j].getName();
}
}
取得其他类的全部属性
Class<?> demo = Class.forName("reflect.Demo");
// 取得本类的全部属性
Field[] fields = demo.getDeclaredFields();
for (int i=0; i<fields.length; i++) {
// 获取修饰符
String modifier = Modifier.toString(fields[i].getModifiers());
// 获取类型
Class<?> type = fields[i].getType();
String typeName = type.getName();
// 获取属性名
String paramName = fields[i].getName();
}
取得实现的接口或者父类的属性
Field[] fieldParam = demo.getFields();
for (int i=0; i<fieldParam.length; i++) {
// 获取修饰符
String modifier = Modifier.toString(fieldParam[i].getModifiers());
// 获取类型
Class<?> type = fieldParam[i].getType();
String typeName = type.getName();
// 获取属性名
String paramName = fieldParam[i].getName();
}
通过反射调用其他类中的方法
Class<?> demo = Class.forName("reflect.Demo");
Method method = demo.getMethod("testMethod");
// 调用Demo中的testMethod方法
method.invoke(demo.newInstance());
调用其他类的set和get方法
Class<?> demo = Class.forName("reflect.Demo");
Object instance = demo.newInstance();
Method setter = demo.getMethod("setAge", int.class);
setter.invoke(instance, 20);
Method getter = demo.getMethod("getAge");
int age = (Integer) getter.invoke(instance);
通过反射操作属性
Class<?> demo = Class.forName("reflect.Demo");
Object instance = demo.newInstance();
Field field = demo.getDeclaredField("age");
// 如果字段是私有的,那么必须要对这个字段设置 field.setAccessible(true) 这样才可以正常使用
field.setAccessible(true);
// 设置属性值
field.set(instance, 30);
// 获得属性值
int age = field.getInt(instance);
取得并修改数组的信息
int[] temp={1,2,3,4,5};
Class<?> demo=temp.getClass().getComponentType();
数组类型:demo.getName();
数组长度:Array.getLength(temp);
数组的第一个元素:Array.get(temp, 0);
设置第一个元素的值为100:Array.set(temp, 0, 100);