java学习--Reflection反射机制

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()

调用有参的构造方法创建新的实例。

java.lang.reflect.Constructor.newInstance(Object... initargs)
Parameters:
initargs array of objects to be passed as arguments to the constructor call; values of primitive types are wrapped in a wrapper object of the 11:20:42type 
对属数组。构造方法中的参数列表
 
运用
新建一个Student类只有简单的姓名年龄
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

上一篇:有向图的强联通tarjan算法(判断是否为强联通模板)(hdu1269)


下一篇:Js_闭包跟作用域