Java反射实战 书籍推荐_Java反射实战

一、背景

最近的项目中需要使用到Java 反射的知识,以前不怎么了解,也基本没怎么用过,抽出一片时间,来具体学习和实战下Java的反射!拿来和大家分享以及记录方便以后学习!

二、反射相关概念解析

1.Class类

Class类:Java程序中的各个Java类属于同一类事物,描述这类事物的Java类名就是Class。

如何得到各个类的字节码即Class类呢?

[1].类名.class:直接通过类.class获得。

[2].对象.getClass():通过对象调用其getClass方法获得。

[3].Class.forName("类全路径"):通过类加载器加载获得

注:Java中的原始基本类型:boolean, byte, char, short, int, long, float,double和关键词 void同样都有Class类,通过.class可获得它们的类字节码。

2.反射的概念

反射就是把Java类中的各种成分映射成相应的Java类,例如一个Java类中用一个Class类的对象表示一个类中的组成部分:成员变量,方法,构造方法,包等等信息也用一个个的Java类来表示,例如人是一个类,那么人的大脑、双手等也是一个个类。表示Java的Class类显然要提供一系列的方法,来获得其中的变量、方法、构造方法,修饰符、包等信息,这些信息就是用相应的类的实例对象来表示,他们是Field、Method、Contructor、Package等等。

一个类中的每个成员都可以用相应的反射API类的一个实例对象来表示。

三、反射实战

测试Bean:Person.java

1 packagecom.hafiz.zhang.Bean;2

3 public classPerson {4 publicInteger id;5 privateString name;6

7 publicPerson() {8 }9 publicPerson(Integer id, String name) {10 super();11 this.id =id;12 this.name =name;13 }14 publicInteger getId() {15 returnid;16 }17 public voidsetId(Integer id) {18 this.id =id;19 }20 publicString getName() {21 returnname;22 }23 public voidsetName(String name) {24 this.name =name;25 }26 @Override27 publicString toString() {28 return "Person [id=" + id + ", name=" + name + "]";29 }30

31 public void sayHello() throwsException{32 System.out.println("Hello Reflect!");33 }34 }

1.使用反射获取对象所属类的全路径(包括报名和类名)

1 packagecom.hafiz.zhang.test;2

3 importcom.hafiz.zhang.Bean.Person;4

5 /**

6 *@authorhafiz.Zhang7 * @Date 2016年5月18日 下午4:28:358 * @Description 测试通过一个对象获取该对象所属于的类的全路径(包括完整包名和类名)9 */

10 public classReflectTest1 {11 public static voidmain(String[] args) {12 Person person = newPerson();13 System.out.println("ClassName = " +person.getClass().getName());14 }15 }

测试结果:

ClassName = com.hafiz.zhang.Bean.Person

2.测试使用反射实例化Class类对象

1 packagecom.hafiz.zhang.test;2

3 importcom.hafiz.zhang.Bean.Person;4

5 /**

6 *@authorhafiz.Zhang7 * @Date 2016年5月18日 下午4:31:368 * @Description 测试获取Class类的三种方式9 */

10 public classReflectTest2 {11 public static voidmain(String[] args) {12 Class> obj1 = null;13 Class> obj2 = null;14 Class> obj3 = null;15 try{16 //一般尽量要采用这种方式进行实例化Class类对象

17 obj1 = (Class>) Class.forName("com.hafiz.zhang.Bean.Person");18 } catch(ClassNotFoundException e) {19 e.printStackTrace();20 }21 obj2 = newPerson().getClass();22 obj3 = Person.class;23

24 System.out.println("ClassName:" +obj1.getName());25 System.out.println("ClassName:" +obj2.getName());26 System.out.println("ClassName:" +obj3.getName());27 }28 }

测试结果:

ClassName:com.hafiz.zhang.Bean.Person

ClassName:com.hafiz.zhang.Bean.Person

ClassName:com.hafiz.zhang.Bean.Person

3.测试通过Class类对象实例化其他类

1 packagecom.hafiz.zhang.test;2

3 importcom.hafiz.zhang.Bean.Person;4

5 /**

6 *@authorhafiz.Zhang7 * @Date 2016年5月18日 下午4:38:158 * @Description 测试通过Class类对象实例化其他类9 */

10 public classReflectTest3 {11 public static voidmain(String[] args) {12 Class> clazz = null;13 try{14 clazz = Class.forName("com.hafiz.zhang.Bean.Person");15 } catch(ClassNotFoundException e) {16 e.printStackTrace();17 }18 Person person = null;19 try{20 person =(Person) clazz.newInstance();21 } catch(InstantiationException e) {22 e.printStackTrace();23 } catch(IllegalAccessException e) {24 e.printStackTrace();25 }26 if(null !=person) {27 person.setId(1);28 person.setName("Hafiz.Zhang");29 System.out.println("person=" +person);30 }else{31 System.out.println("实例化对象失败");32 }33 }34 }

测试结果:

person=Person [id=1, name=Hafiz.Zhang]

4.测试通过Class调用其他类中的构造函数 (也可以通过这种方式通过Class创建其他类的对象)

1 packagecom.hafiz.zhang.test;2

3 importjava.lang.reflect.Constructor;4 importjava.lang.reflect.InvocationTargetException;5

6 importcom.hafiz.zhang.Bean.Person;7

8 /**

9 *@authorhafiz.Zhang10 * @Date 2016年5月18日 下午4:42:0811 * @Description 测试通过Class调用其他类中的构造函数 (也可以通过这种方式通过Class创建其他类的对象)12 */

13 public classReflectTest4 {14 public static voidmain(String[] args) {15 Class> clazz = null;16 try{17 clazz = Class.forName("com.hafiz.zhang.Bean.Person");18 } catch(ClassNotFoundException e) {19 e.printStackTrace();20 }21 Person p1 = null;22 Person p2 = null;23 Constructor>[] cs =clazz.getConstructors();24 try{25 p1 = (Person) cs[0].newInstance();//通过无参构造获得对象26 p2 = (Person) cs[1].newInstance(1, "Hafiz.Zhang");//通过有参构造获得对象27 } catch(InstantiationException e) {28 e.printStackTrace();29 } catch(IllegalAccessException e) {30 e.printStackTrace();31 } catch(IllegalArgumentException e) {32 e.printStackTrace();33 } catch(InvocationTargetException e) {34 e.printStackTrace();35 }36 System.out.println("Person1=" +p1);37 System.out.println("Person2=" +p2);38 }39 }

测试结果:

Person1=Person [id=null, name=null]

Person2=Person [id=1, name=Hafiz.Zhang]

5.测试使用反射获取一个类实现的接口

接口Animal.java

1 packagecom.hafiz.zhang.Bean;2

3 /**

4 *@authorhafiz.Zhang5 * @Date 2016年5月19日 下午6:13:376 * @Description 动物接口7 */

8 public interfaceAnimal {9 public abstract voideat();10 public abstract voidsleep();11 }

接口Skill.java

1 packagecom.hafiz.zhang.Bean;2

3 /**

4 *@authorhafiz.Zhang5 * @Date 2016年5月19日 下午6:14:066 * @Description 技能接口7 */

8 public interfaceSkill {9 public abstract voidsayMiao();10 }

实现类:Cat.java

1 packagecom.hafiz.zhang.Bean;2

3 public class Cat implementsAnimal, Skill {4 privateInteger num;5 privateString desc;6 publicInteger getNum() {7 returnnum;8 }9

10 public voidsetNum(Integer num) {11 this.num =num;12 }13

14 publicString getDesc() {15 returndesc;16 }17

18 public voidsetDesc(String desc) {19 this.desc =desc;20 }21

22 @Override23 public voideat() {24 System.out.println("cat eat fish");25 }26

27 @Override28 public voidsleep() {29 System.out.println("cat sleep in the day");30 }31

32 @Override33 public voidsayMiao() {34 System.out.println("cat say miao");35 }36

37 public voidsayHello(String name){38 System.out.println("Hello " +name);39 }40 }

测试类

1 packagecom.hafiz.zhang.test;2

3 /**

4 *@authorhafiz.Zhang5 * @Date 2016年5月18日 下午4:51:296 * @Description 测试使用反射获取一个类实现的接口7 */

8 public classReflectTest5 {9 public static voidmain(String[] args) {10 Class> clazz = null;11 try{12 clazz = Class.forName("com.hafiz.zhang.Bean.Cat");13 } catch(ClassNotFoundException e) {14 e.printStackTrace();15 }16 Class>[] interfaces =clazz.getInterfaces();17 System.out.println("Cat实现的接口有");18 for(Class>cl : interfaces) {19 System.out.println(cl.getName());20 }21 }22 }

测试结果:

Cat实现的接口有

com.hafiz.zhang.Bean.Animal

com.hafiz.zhang.Bean.Skill

6.测试通过反射取得指定类的父类

1 packagecom.hafiz.zhang.test;2

3 /**

4 *@authorhafiz.Zhang5 * @Date 2016年5月18日 下午5:03:256 * @Description 测试通过反射取得指定类的父类7 */

8 public classReflectTest6 {9 public static voidmain(String[] args) {10 Class> clazz = null;11 try{12 clazz = Class.forName("com.hafiz.zhang.Bean.Cat");13 } catch(ClassNotFoundException e) {14 e.printStackTrace();15 }16 Class> superClass =clazz.getSuperclass();17 System.out.println("SuperClass=" +superClass);18 }19 }

测试结果:SuperClass=class com.hafiz.zhang.Bean.Person

7.测试通过反射获得其他类中的全部构造函数

1 packagecom.hafiz.zhang.test;2

3 importjava.lang.reflect.Constructor;4 importjava.lang.reflect.Modifier;5

6 /**

7 *@authorhafiz.Zhang8 * @Date 2016年5月18日 下午5:06:029 * @Description 测试通过反射获得其他类中的全部构造函数10 */

11 public classReflectTest7 {12 public static voidmain(String[] args) {13 Class> clazz = null;14 try{15 clazz = Class.forName("com.hafiz.zhang.Bean.Person");16 } catch(ClassNotFoundException e) {17 e.printStackTrace();18 }19 Constructor>[] cs =clazz.getConstructors();20 //实现方式1

21 /*for(Constructor> item : cs) {22 System.out.println("构造方法:" + item.getName());23 }*/

24 //实现方式2

25 for(Constructor>item : cs) {26 System.out.print("构造方法:");27 System.out.print(Modifier.toString(item.getModifiers()) + " ");28 System.out.print(item.getName() + "(");29 Class>[] paramterTypes =item.getParameterTypes();30 for(int i = 0; i < paramterTypes.length; i++) {31 System.out.print(paramterTypes[i].getName() + " arg" +i);32 if(i < paramterTypes.length-1) {33 System.out.print(",");34 }35 }36 System.out.println(")");37 }38 }39 }

测试结果:

构造方法:public com.hafiz.zhang.Bean.Person()

构造方法:public com.hafiz.zhang.Bean.Person(java.lang.Integer arg0,java.lang.String arg1)

8. 测试通过反射获取类中的所有方法(包括方法包含的异常)

1 packagecom.hafiz.zhang.test;2

3 importjava.lang.reflect.Method;4 importjava.lang.reflect.Modifier;5

6 /**

7 *@authorhafiz.Zhang8 * @Date 2016年5月18日 下午5:22:519 * @Description 测试通过反射获取类中的所有方法10 */

11 public classReflectTest8 {12 public static voidmain(String[] args) {13 Class> clazz = null;14 try{15 clazz = Class.forName("com.hafiz.zhang.Bean.Person");16 } catch(ClassNotFoundException e) {17 e.printStackTrace();18 }19 Method[] methods =clazz.getDeclaredMethods();20 for(Method method : methods) {21 Class> returnType =method.getReturnType();22 System.out.print(Modifier.toString(method.getModifiers()) + " ");23 System.out.print(returnType.getName() + " " + method.getName() + "(");24 Class>[] paras =method.getParameterTypes();25 for(int i = 0 ; i < paras.length ; i++) {26 System.out.print(paras[i].getName() + " arg" +i);27 if(i < paras.length - 1) {28 System.out.print(",");29 }30 }31 Class>[] exces =method.getExceptionTypes();32 if(exces.length > 0) {33 System.out.print(") throws ");34 for(int j = 0; j < exces.length; j++) {35 System.out.print(exces[j].getName());36 if(j < exces.length - 1) {37 System.out.print(", ");38 }39 }40 }else{41 System.out.print(")");42 }43 System.out.println();44 }45 }46 }

测试结果:

public java.lang.String toString()

public java.lang.String getName()

public void setName(java.lang.String arg0)

public java.lang.Integer getId()

public void sayHello() throws java.lang.Exception

public void setId(java.lang.Integer arg0)

9.测试通过反射获取类中所有的属性

1 packagecom.hafiz.zhang.test;2

3 importjava.lang.reflect.Field;4 importjava.lang.reflect.Modifier;5

6 /**

7 *@authorhafiz.Zhang8 * @Date 2016年5月18日 下午5:38:099 * @Description 测试通过反射获取类中所有的属性10 */

11 public classReflectTest9 {12 public static voidmain(String[] args) {13 Class> clazz = null;14 try{15 clazz = Class.forName("com.hafiz.zhang.Bean.Cat");16 } catch(ClassNotFoundException e) {17 e.printStackTrace();18 }19 Field[] fields =clazz.getDeclaredFields();20 System.out.println("=========通过反射获取指定类中所有的属性=========");21 for(Field field : fields) {22 System.out.println(Modifier.toString(field.getModifiers()) + " " + field.getType().getName() + " " +field.getName());23 }24 System.out.println("=========通过反射获取指定类实现的接口或者父类中所有的属性=========");25 Field[] fields2 =clazz.getSuperclass().getDeclaredFields();26 for(Field item : fields2) {27 System.out.println(Modifier.toString(item.getModifiers()) + " " + item.getType() + " " +item.getName());28 }29 }30 }

测试结果:

=========通过反射获取指定类中所有的属性=========

private java.lang.Integer num

private java.lang.String desc

=========通过反射获取指定类实现的接口或者父类中所有的属性=========

public class java.lang.Integer id

private class java.lang.String name

10.测试使用反射调用指定类的方法

1 packagecom.hafiz.zhang.test;2

3 importjava.lang.reflect.InvocationTargetException;4 importjava.lang.reflect.Method;5

6 /**

7 *@authorhafiz.Zhang8 * @Date 2016年5月19日 下午3:22:339 * @Description 测试使用反射调用指定类的方法10 */

11 public classReflectTest10 {12 public static voidmain(String[] args) {13 Class> clazz = null;14 try{15 clazz = Class.forName("com.hafiz.zhang.Bean.Cat");16 } catch(ClassNotFoundException e) {17 e.printStackTrace();18 }19 try{20 //调用Cat类中的eat无参方法

21 Method method = clazz.getMethod("eat");22 method.invoke(clazz.newInstance());23 //调用Cat类中的sayHello有参方法

24 Method method2 = clazz.getDeclaredMethod("sayHello", String.class);25 method2.invoke(clazz.newInstance(), "Hafiz.Zhang");26 } catch(NoSuchMethodException e) {27 e.printStackTrace();28 } catch(SecurityException e) {29 e.printStackTrace();30 } catch(IllegalAccessException e) {31 e.printStackTrace();32 } catch(IllegalArgumentException e) {33 e.printStackTrace();34 } catch(InvocationTargetException e) {35 e.printStackTrace();36 } catch(InstantiationException e) {37 e.printStackTrace();38 }39 }40 }

测试结果:

cat eat fish

Hello Hafiz.Zhang

11.测试通过反射调用其他类中的setter和getter方法

1 packagecom.hafiz.zhang.test;2

3 importjava.lang.reflect.InvocationTargetException;4 importjava.lang.reflect.Method;5

6 /**

7 *@authorhafiz.Zhang8 * @Date 2016年5月19日 下午3:29:349 * @Description 测试通过反射调用其他类中的setter和getter方法10 */

11 public classReflectTest11 {12 public static voidmain(String[] args) {13 Class> clazz = null;14 Object obj = null;15 try{16 clazz = Class.forName("com.hafiz.zhang.Bean.Cat");17 obj =clazz.newInstance();18 } catch(ClassNotFoundException e) {19 e.printStackTrace();20 } catch(InstantiationException e) {21 e.printStackTrace();22 } catch(IllegalAccessException e) {23 e.printStackTrace();24 }25 getter(obj,"Desc");26 setter(obj,"Desc","测试调用set方法",String.class);27 getter(obj,"Desc");28 }29

30 private static voidgetter(Object obj, String name) {31 try{32 Method method = obj.getClass().getMethod("get"+name);33 System.out.println(name + ":" +method.invoke(obj));34 } catch(NoSuchMethodException e) {35 e.printStackTrace();36 } catch(SecurityException e) {37 e.printStackTrace();38 } catch(IllegalAccessException e) {39 e.printStackTrace();40 } catch(IllegalArgumentException e) {41 e.printStackTrace();42 } catch(InvocationTargetException e) {43 e.printStackTrace();44 }45 }46

47 private static void setter(Object obj, String name, String desc, Class>type) {48 try{49 Method method = obj.getClass().getMethod("set" +name, type);50 method.invoke(obj, desc);51 } catch(NoSuchMethodException e) {52 e.printStackTrace();53 } catch(SecurityException e) {54 e.printStackTrace();55 } catch(IllegalAccessException e) {56 e.printStackTrace();57 } catch(IllegalArgumentException e) {58 e.printStackTrace();59 } catch(InvocationTargetException e) {60 e.printStackTrace();61 }62 }63 }

测试结果:

Desc:null

Desc:测试调用set方法

12.测试通过反射操作属性

1 packagecom.hafiz.zhang.test;2

3 importjava.lang.reflect.Field;4

5 /**

6 *@authorhafiz.Zhang7 * @Date 2016年5月19日 下午3:41:598 * @Description 测试通过反射操作属性9 */

10 public classReflectTest12 {11 public static voidmain(String[] args) {12 Class> clazz = null;13 Object obj = null;14 try{15 clazz = Class.forName("com.hafiz.zhang.Bean.Cat");16 obj =clazz.newInstance();17 Field field = clazz.getDeclaredField("desc");18 //若要设置private属性,需要设置

19 field.setAccessible(true);//设置成员变量可访问,包括private成员变量(暴力反射),private成员通过这步操作才能被访问20 field.set(obj, "this is test demo");21 System.out.println("Desc=" +field.get(obj));22 } catch(ClassNotFoundException e) {23 e.printStackTrace();24 } catch(InstantiationException e) {25 e.printStackTrace();26 } catch(IllegalAccessException e) {27 e.printStackTrace();28 } catch(NoSuchFieldException e) {29 e.printStackTrace();30 } catch(SecurityException e) {31 e.printStackTrace();32 }33

34 }35 }

测试结果:Desc=this is test demo

13.测试通过反射进行数组操作

1 packagecom.hafiz.zhang.test;2

3 importjava.lang.reflect.Array;4

5 /**

6 *@authorhafiz.Zhang7 * @Date 2016年5月19日 下午4:52:218 * @Description 测试通过反射进行数组操作9 *10 */

11 public classReflectTest13 {12 public static voidmain(String[] args) {13 Integer[] array = {1,2,3,4,5,6};14 Class> clazz =array.getClass().getComponentType();15 System.out.println("数组类型:" +clazz.getName());16 System.out.println("数组长度:" +Array.getLength(array));17 System.out.println("数组第一个元素:" + Array.get(array, 0));18 Array.set(array, 0, 8);19 System.out.println("修改之后数组第一个元素:" + Array.get(array, 0));20 System.out.println("=============反射修改数组长度=================");21 Integer[] arr2 = (Integer[])changeLength(array, 10);22 print(arr2);23 }24 private static voidprint(Object obj) {25 Class> clazz =obj.getClass();26 if(!clazz.isArray()) {27 return;28 }29 System.out.println("数组长度为:" +Array.getLength(obj));30 for(int i = 0; i < Array.getLength(obj); i++){31 System.out.print(Array.get(obj, i) + " ");32 }33 }34 public staticObject changeLength(Object obj, Integer length){35 Class> clazz =obj.getClass().getComponentType();36 Object newArr =Array.newInstance(clazz, length);37 Integer len =Array.getLength(obj);38 System.arraycopy(obj, 0, newArr, 0, len);39 returnnewArr;40 }41 }

测试结果:

数组类型:java.lang.Integer

数组长度:6

数组第一个元素:1

修改之后数组第一个元素:8

=============反射修改数组长度=================

数组长度为:10

8 2 3 4 5 6 null null null null

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值