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);
}
}
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);
}
}
相关文章推荐
- Java虚拟机分类整理
- JavaWeb - 知识点
- SpringMVC整合Shiro
- java多线程
- 手把手实现Java权限(1)-Shiro介绍
- JDK8 ——lambda表达式
- java web的图片上传问题
- 初识——java中的类与对象
- Java十进制转二进制,递归算法
- 《Java程序设计基础》 第7章手记
- [Java]包与包之间的调用
- Java中重载与重写区别
- [JAVA · 初级]:15.异常处理机制
- Java数据库连接——JDBC基础知识(操作数据库:增删改查)
- Java之JDBC对接MySql
- Java NIO - volatile
- 新手笔记:java集合汇总
- Poj 1451 JAVA 个人解题报告
- Java泛型需要注意的地方
- java面向对象_内存分析1