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

Java的反射(二)

2014-01-08 22:43 281 查看
在前面我们已经谈了一些关于Java反射的一些概念,下面我们就写一个小程序来说明一下Java反射的应用。

以下的程序,使用了Java的反射获取类的属性,调用类的方法(包括构造方法),这里要说明的是,在这个例子中也使用到了Java反射中的所谓“暴力反射”的特性,即使用反射调用类的私有方法或属性,不过需要注意的是在使用这一特性时,要先调用setAccessible方法将其设为true,还有一点就是不管是类的Constructor,Method,Field都有两类方法,分别是getXXX,getDeclaredXXX的两类,简单的区别就是私有的(private)和受保护(protected)类型的方法或是属性需要使用getDeclaredXXX方法来获取,而公有的用getXXX即可,特别详细的区别看下图,这个是oracle官网Java教程中给出的:



这里为了能够相对全面的说明Java的反射特性所以在类的方法或属性上的定义比较多样。

首先我们建立一个普通的Person类:

public class Person {

private String name = "aaaaaaaaaaa";
public int age = 20;
protected String addr = "china";

public Person(){}

public Person(String name){
this.name = name;
}

private Person(String name, int age){
this.name = name;
this.age = age;
}

public void print(){
System.out.println("Person's name: "+this.name+",age: "+age);
}

private void display(String str){
System.out.println(str);
}

private static void show(String str){
System.out.println("调用静态方法测试"+str);
}

}


反射的测试类:ReflectTest

public class ReflectTest {

public static void main(String[] args) throws Exception {

Class<Person> clazz = Person.class;
// 通过反射获取Person类的默认的构造方法(无参的构造方法)
Constructor<Person> constructor1 = clazz.getConstructor();
// 利用反射调用Person的无参的构造方法,构造Person对象
Person person1 = constructor1.newInstance();
person1.print();

// 利用反射调用Person的有参的构造方法
Constructor<Person> constructor2 = clazz.getConstructor(String.class);
Person person2 = constructor2.newInstance("constructor2");
person2.print();

// 利用反射调用Person的私有构造方法(这里就是常说的暴力反射),注意getConstructor,getDeclaredConstructor方法的区别
Constructor<Person> constructor3 = clazz.getDeclaredConstructor(String.class);
// 在调用私有方法或属性之前必须要设置此属性为true
constructor3.setAccessible(true);
Person person3 = constructor3.newInstance("constructor3");
person3.print();

// 利用反射获取Person类的属性,注意:getDeclaredField,getField方法的区别
Field name = clazz.getDeclaredField("name");//获取name属性,私有属性
Field age = clazz.getField("age");// 获取age属性
Field addr = clazz.getDeclaredField("addr");// 获取addr属性,受保护类型
name.setAccessible(true);
System.out.println("name: "+name.get(person1)+" age: "+age.get(person1)+" addr: "+addr.get(person1));

// 对属性值进行修改
name.set(person1, "testperson");
age.setInt(person1, 23);
addr.set(person1, "Beijing");
System.out.println("name: "+name.get(person1)+" age: "+age.get(person1)+" addr: "+addr.get(person1));

// 利用反射获取Person类的方法
Method m1 = clazz.getMethod("print");// 获取print方法
m1.invoke(person1);
Method m2 = clazz.getDeclaredMethod("display", String.class);// 获取display方法,私有方法
m2.setAccessible(true);
m2.invoke(person1, "display");

Method m3 = clazz.getDeclaredMethod("show", String.class);// 获取show方法,静态私有方法
m3.setAccessible(true);
m3.invoke(null, "static show");// 在调用静态方法时,不需要指定对象是谁,直接传null就可
}

}


这里只是就反射的一些常用的方法进行了实践,其实反射的使用是非常的灵活和强大,在Java的很多框架包括大家熟知的Hibernate,Spring等以及一些基础类库都用到了Java的反射特性
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: