Java的反射(二)
2014-01-08 22:43
281 查看
在前面我们已经谈了一些关于Java反射的一些概念,下面我们就写一个小程序来说明一下Java反射的应用。
以下的程序,使用了Java的反射获取类的属性,调用类的方法(包括构造方法),这里要说明的是,在这个例子中也使用到了Java反射中的所谓“暴力反射”的特性,即使用反射调用类的私有方法或属性,不过需要注意的是在使用这一特性时,要先调用setAccessible方法将其设为true,还有一点就是不管是类的Constructor,Method,Field都有两类方法,分别是getXXX,getDeclaredXXX的两类,简单的区别就是私有的(private)和受保护(protected)类型的方法或是属性需要使用getDeclaredXXX方法来获取,而公有的用getXXX即可,特别详细的区别看下图,这个是oracle官网Java教程中给出的:
![](https://img-blog.csdn.net/20140108223615765?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcHpzb2Z0Y2hlbg==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
这里为了能够相对全面的说明Java的反射特性所以在类的方法或属性上的定义比较多样。
首先我们建立一个普通的Person类:
反射的测试类:ReflectTest
这里只是就反射的一些常用的方法进行了实践,其实反射的使用是非常的灵活和强大,在Java的很多框架包括大家熟知的Hibernate,Spring等以及一些基础类库都用到了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的反射特性
相关文章推荐
- spring学习笔记(三)
- java 扫描局域网中的ip
- Spring框架4.0 GA版本发布
- JAVA中的反射机制
- Java -- 注解 annotation
- Spring面试问题
- Java -- 注解 annotation
- Java内部类的使用小结
- 《JAVA从入门到精通》学习笔记10-12章
- java 环境变量配置 图文版
- Spring3整合Struts2+Hibernate 实现注册、数据库验证登陆
- 解决Eclipse的快捷提示弹出过快的问题
- [Leetcode] Rotate List (Java)
- Spring 使用注解方式进行事物管理
- Java知识总结-内部类
- Java知识总结-内部类
- Myeclipse(eclipse)中自动注释格式设置
- struts2学习笔记
- instanceof的理解
- Java——协变数组和类型擦除(covariant array & type erasure)