一.什么是反射机制
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。(百度)
我自己的理解是在程序运行时,通过类名获得类的信息,在不改变类的源代码的同时可以对类中的属性和方法进行操作(修改),这样增加了程序的灵活性,体现了java的动态性。
二.怎样实现反射(这里用一个test1类作演示)
首先要操作一个类,那么就应该先得到这个类,这里必须提到前面说过的面向对象的理解,那就是万物皆对象,所有类都是Class类的一个对象,类中的属性和方法其实也是对象。
类中的构造方法————Constructor类的对象
类中的普通方法————Method类的对象
类中的属性————Field类的对象
下面谈谈获得Class类的类对象(要操作的类)的三种方法
1.Object类中有getclass()方法,可以根据要操作类的对象调用。
2.所有数据类型都有一个Class属性,可以通过调用该属性获得。
3.Class类中有静态方法forname(String classname),可以通过调用该方法获得(最常用)。
下面贴代码演示:
//第一种方法
test1 test=new Test1();
Class class1=test.getClass();
System.out.println(class1.getname());
//第二种方法
Class class2=test1.class;
System.out.println(class2.getname());
//第三种方法
Class class1=Class.forName("com.wc.fanshe0912.test1");
得到了Class对象之后就可以去获得类中的属性、方法和构造方法了
下面就直接贴测试代码了,值得注意的是调用公有的属性、方法和构造方法都是照葫芦画瓢就行了,但是调用其他访问权限的属性或者方法的时候,要先解除访问限定。
public class Test {
public static void main(String[] args) {
// TODO Auto-generated method stub
try {
//返回要操作的Class对象
Class class1=Class.forName("com.wc.fanshe0912.test1");
//得到该类的所有的公有构造方法
System.out.println("所有的公有构造方法--------------------------------");
Constructor[] con=class1.getConstructors();
for(Constructor c:con){
System.out.println(c);
}
//获取所有的构造方法(包括默认、protected和private)
System.out.println("所有的构造方法===================================");
con=class1.getDeclaredConstructors();
for(Constructor c :con){
System.out.println(c);
}
//调用无参构造方法
Constructor con1 = class1.getConstructor(null);
Object ob=con1.newInstance();
//调用有1个参数的私有构造方法
con1=class1.getDeclaredConstructor(int.class,int.class);
//解除私有限定
con1.setAccessible(true);
ob=con1.newInstance(3,5);
//得到该类的普通方法
Method me=class1.getMethod("test2");
System.out.println(me);
//实例化对象
Object obj=class1.newInstance();
//通过Object对象调用该普通方法
me.invoke(obj);
System.out.println("类中的所有公有属性--------------------------------");
//通过Class得到类中声明的属性
java.lang.reflect.Field[] fi=class1.getFields();
//获得所有的公有属性并相继打印输出
for(java.lang.reflect.Field f:fi){
System.out.println(f);
}
//获得单独的公有属性
java.lang.reflect.Field fie=class1.getField("a");
System.out.println(fie.get(obj));
//获得私有属性
java.lang.reflect.Field fie1=class1.getDeclaredField("b");
//取消访问限制
fie1.setAccessible(true);
System.out.println(fie1.get(obj));
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
// } catch (NoSuchFieldException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchFieldException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
测试类Test1
public class test1 {
public int a=1;
public int c=2;
private int b=3;
public test1(){
System.out.println("调用了无参构造方法");
}
private test1(int a){
c=a;
System.out.println("调用了有参数的构造方法- - "+c);
}
private test1(int a,int b){
System.out.println("调用了私有的构造方法---"+a+b);
}
public void test2(){
System.out.println("成功调用了普通方法");
}
}
后台输出:
所有的公有构造方法--------------------------------
public com.wc.fanshe0912.test1()
所有的构造方法===================================
private com.wc.fanshe0912.test1(int,int)
private com.wc.fanshe0912.test1(int)
public com.wc.fanshe0912.test1()
调用了无参构造方法
调用了私有的构造方法---35
public void com.wc.fanshe0912.test1.test2()
调用了无参构造方法
成功调用了普通方法
类中的所有公有属性--------------------------------
public int com.wc.fanshe0912.test1.a
public int com.wc.fanshe0912.test1.c
1
3
获得构造函数的方法
Constructor getConstructor(Class[] params)//根据指定参数获得public构造器
Constructor[] getConstructors()//获得public的所有构造器
Constructor getDeclaredConstructor(Class[] params)//根据指定参数获得public和非public的构造器
Constructor[] getDeclaredConstructors()//获得public的所有构造器
获得类方法的方法
Method getMethod(String name, Class[] params),根据方法名,参数类型获得方法
Method[] getMethods()//获得所有的public方法
Method getDeclaredMethod(String name, Class[] params)//根据方法名和参数类型,获得public和非public的方法
Method[] getDeclaredMethods()//获得所以的public和非public方法
获得类中属性的方法
Field getField(String name)//根据变量名得到相应的public变量
Field[] getFields()//获得类中所以public的方法
Field getDeclaredField(String name)//根据方法名获得public和非public变量
Field[] getDeclaredFields()//获得类中所有的public和非public方法