JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。
Java反射机制主要提供了以下功能:
1. 在运行时判断任意一个对象所属的类;
Integer aInteger = Integer.valueOf(120); boolean isEqual = Integer.class.isInstance(bInteger);
判断aInteger对象是否是Integer类的实例,返回的值是true
2. 在运行时构造任意一个类的对象;
Class clazz = Class.forName("java.lang.Strings");
String newString = (String) clazz.newInstance();
这个class只能调用类的无参构造方法,如果需要调用有参构造方法需要使用Constractor.newInstace方法
3. 在运行时判断任意一个类所具有的成员变量和方法;
getFields和getMethods方法获取所有非private的变量和方法数组
4. 在运行时调用任意一个对象的方法;生成动态代理。
Class<?> clazz = Class.forName("java.lang.String"); String newString = (String) clazz.newInstance(); newString = "123456789"; Method lengthMethod = clazz.getMethod("length"); int length = (int) lengthMethod.invoke(newString); System.out.println("字符串长度:"+length);
//输出
字符串长度:9
不华丽得分割线
Java有个Object 类,是所有Java 类的继承根源。其中方法getClass()返回一个Class 对象。
Class没有public constructor。只有一个private constructor
private Class() {},意指不允许任何人经由编程方式产生Class object。是的,其object 只能由JVM 产生。
Class是Reflection故事起源。针对任何您想探勘的类,唯有先为它产生一个Class 对象,接下来才能经由后者唤起为数十多个的Reflection APIs。
Member接口 该接口可以获取有关类成员(域或者方法)后者构造函数的信息。 AccessibleObject类 该类是域(field)对象、方法(method)对象、构造函数(constructor)对象的基础类。它提供了将反射的对象标记为在使用时取消默认 Java 语言访问控制检查的能力。 Array类 该类提供动态地生成和访问JAVA数组的方法。 Constructor类 提供一个类的构造函数的信息以及访问类的构造函数的接口。 Field类 提供一个类的域的信息以及访问类的域的接口。 Method类 提供一个类的方法的信息以及访问类的方法的接口。 Modifier类 提供了 static 方法和常量,对类和成员访问修饰符进行解码。 Proxy类 提供动态地生成代理类和类实例的静态方法。
获取Class方式
getClass()、
Sting s1="123"
Class clazz=s1.getClass()
getSuperclass()、
Class superClazz=clazz.getSuperclass()
运用.class 语法
Class clazz=String.class
运用static method------Class.forName()(最常被使用)
Class clazz=Class.forName("java.lang.String")包名加类名
运用primitive wrapper classes的TYPE 语法这里返回的是原生类型,和Boolean.class返回的不同
基本数据类型及其包装类型才有
Class<?> clazz=Integer.TYPE;//输出为int
Class<?> clazz=int.class//输出为int
Class<?> clazz=Integer.class//输出为class java.lang.Integer
获取类的Fields
Field getField(String name)获取对应name的field对象 即获取对应name的字段
Field[] getFields()获得对象内所有public字段的field对象数组
上面这两个只能获得所有public修饰符修饰的所有字段
Field[] getDeclaredFields()获得本对象或接口内定义的所有field对象数组(包括public, protected, default (package) access, and private fields)。
不包括继承的字段。
This includes public, protected, default (package) access, and private fields, but excludes inherited fields.
Field getDeclaredField(String name)这也只能获得本对象或接口定义的字段,不包括继承字段
这两个declared方法可以获得本对象或接口内的所有字段包括public、protected、private、缺省修饰的字段,但不包括继承的字段
运用,下面的Student类举例
获取Student类定义的所有变量
Class<?> clazz=Student.class;
Field[] fields = clazz.getDeclaredFields(); for(Field f:fields){ f.setAccessible(true); System.out.println(f.getName()+"变量类型"+f.getGenericType()+"变量值"+(String)f.get(clazz)); }
setAccessible(true)是为了能够访问private私有变量,否则当访问到是一个private 变量时会抛出异常。
Set the accessible flag for this object to the indicated boolean value. A value of true indicates that the reflected object should suppress Java language access checking when it is used. A value of false indicates that the reflected object should enforce Java language access checks.
当设值为true时这个反射对象应该禁止java语言访问检查
值为false表示反射对象应强制实施Java语言访问检查。
如果是要获取基本类型的值,有特定的方法可以调用类似getXxx(obj)
如获取整形getInt(obj)
获取类的Method
通过反射机制得到某个类的某个方法,然后调用对应于这个类的某个实例的该方法
Method[] getMethods()同上获取所有共有方法的method对象数组
Method getMethod(String name, Class<?>... parameterTypes)
Method[] getDeclaredMethods()
Method getDeclaredMethod(String name, Class<?>... parameterTypes)
方法的说明和field变量/字段的说明相同。
参数后面解释
获取类的Constructor
Constructor<?>[] getConstructors()
Constructor<T> getConstructor(Class<?>... parameterTypes)
Constructor<?>[] getDeclaredConstructors()
Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)
新建类的实例(对象)
调用无参的构造方法创建新的实例时2种方法
Creates a new instance of the class represented by this Class object. The class is
如果这个类没有被实例化,则创建一个新的类的实例,这个类是被无参数列表的构造方法实例化了 instantiated as if by a new expression with an empty argument list. The class is initialized if it has not already been initialized
Class.newInstance()
Constructor.newInstance()
调用有参的构造方法创建新的实例。
public class Student { public int age; String name; public Student(){ this.age = 0; this.name="default name"; } public Student(int age, String name) { super(); this.age = age; this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
1、获得class类2、获得class类实例3、获得class类中指定方法4、反射调用该方法
Class<?> clazz=Student.class; //System.out.println(clazz); //Object inst = clazz.newInstance(); Constructor<?> constractor=clazz.getDeclaredConstructor(int.class,String.class); Object inst=constractor.newInstance(11,"德玛西亚"); Method getNameMethod=clazz.getDeclaredMethod("getName"); //Type methodType=getNameMethod.getReturnType(); String stuName=(String) getNameMethod.invoke(inst);
System.out.println("clazz:"+clazz);
System.out.println("inst:"+inst);
System.out.println("方法返回值类型"+methodType);
System.out.println("返回值为"+stuName);
clazz:class Student
inst:Student@15db9742
方法返回值类型class java.lang.String
返回值为德玛西亚
创建动态代理
java.lang.reflect.Proxy
Proxy 提供用于创建动态代理类和实例的静态方法,它还是由这些方法创建的所有动态代理类的超类
InvocationHandler
是代理实例的调用处理程序 实现的接口,每个代理实例都具有一个关联的调用处理程序。对代理实例调用方法时,将对方法调用进行编码并将其指派到它的调用处理程序的 invoke 方法。
抽象角色:声明真实对象和代理对象的共同接口
代理角色:代理角色内部包含有真实对象的引用,从而可以操作真实对象。
真实角色:代理角色所代表的真实对象,是我们最终要引用的对象。
用不到的以后再补充
经验有限,为防止忘记,做学习记录使用。
参考资料http://blog.csdn.net/yongjian1092/article/details/7364451