您的位置:首页 > 编程语言 > Java开发

Java反射机制

2016-04-03 15:27 387 查看
Class类

Java反射的基础是,Java会为每一个类常见一个java.lang.Class类的实例,通过该对象可以获取这个类的信息。
Java中把一个类加载到JVM中,就是把这个类(所有类都继承自Object,包括Class类)的Class类对象加载到JVM中去,每个加载到JVM的类都有一个对应的Class类实例。一个Class类实例包含的是一个Java类的全部信息,包括类名,方法,属性等。
一般情况下,如果要生成一个类的对象,JVM会确认这个类的Class对象是否已经被加载,如果尚未加载,JVM会根据类名来查找.class文件,并将其载入,如果这个类的Class对象已经被加载到内存中,他就可以用来创建这个类的对象。

类什么时候加载到JVM中
(1)创建一个累的对象时。 Object obj=new Object();
(2)访问类的静态成员时。
(3)使用Class类的静态方法forName(),动态加载一个指定类名的类。 Class.forName("name");

如何得到一个类的Class对象
(1)Class的forName()方法的返回值就是Class类型,就是动态加载的类的Class对象的引用。
(2)每个类都会有一个class的静态属性。
(3)Object类有一个getClass成员方法,所有的类都继承自Object类。

通过反射操作类的成员变量(Field类)

Field类位于java.lang.reflect包下,Field类的方法主要分为set和get两类。Field对象通过Class类的getDeclaredField()和getDeclaredFields()方法获得。
操作类成员的示例:

MyInt myInt = new MyInt(1);
change(myInt);

private static void change(Object obj) {
try {
Field field = obj.getClass().getDeclaredField("num");
field.setAccessible(true);// 设置可访问为true,私有成员也可以访问
System.out.println((Integer) field.get(obj));
field.set(obj, 2);
System.out.println((Integer) field.get(obj));

} catch (NoSuchFieldException | SecurityException
| IllegalArgumentException | IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

class MyInt {
public int num;
public MyInt(int a) {
this.num = a;
}
}

如何操作类的函数(Method类)

Method对象通过Class类的getMethod()或者getMethods()方法得到。Method类中使用最多的方法是invoke方法,它的第一个参数为Class所代表的类的一个实例对象,以后的参数则是一个不定长的Object类型的参数列表(相对应的方法的参数列表)。

MyInt myInt = new MyInt(1);
invokeByReflect(myInt);

private static void invokeByReflect(Object obj) {
try {
Method method = obj.getClass().getMethod("p", int.class);
method.invoke(obj, 2);
} catch (SecurityException | IllegalArgumentException
| IllegalAccessException | InvocationTargetException
| NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

class MyInt {
public int num;
public MyInt(int a) {
this.num = a;
}
public void p(int a) {
System.out.println(a);
}
}

使用反射实例化一个类

如果此类有无参的构造函数,则直接调用Class类的newInstance()方法,如果需要使用类的特定的构造方法,则需要获取去Constructor实例,再用newInstance()方法创建对象。

MyInt myInt=null;
try {
myInt=MyInt.class.newInstance();//无参
} catch (InstantiationException | IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
Constructor<MyInt> cons=MyInt.class.getConstructor(int.class);
myInt=cons.newInstance(3);//有参数
} catch (NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

class MyInt {
public int num;
public MyInt() {
}
public MyInt(int a) {
this.num = a;
}
public void p(int a) {
System.out.println(a);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: