Java反射实战
2016-05-19 18:41
435 查看
一、背景
最近的项目中需要使用到Java 反射的知识,以前不怎么了解,也基本没怎么用过,抽出一片时间,来具体学习和实战下Java的反射!拿来和大家分享以及记录方便以后学习!
二、反射相关概念解析
1.Class类
Class类:Java程序中的各个Java类属于同一类事物,描述这类事物的Java类名就是Class。
如何得到各个类的字节码即Class类呢?
[1].类名.class:直接通过类.class获得。
[2].对象.getClass():通过对象调用其getClass方法获得。
[3].Class.forName("类全路径"):通过类加载器加载获得
注:Java中的原始基本类型:boolean,
2.反射的概念
反射就是把Java类中的各种成分映射成相应的Java类,例如一个Java类中用一个Class类的对象表示一个类中的组成部分:成员变量,方法,构造方法,包等等信息也用一个个的Java类来表示,例如人是一个类,那么人的大脑、双手等也是一个个类。表示Java的Class类显然要提供一系列的方法,来获得其中的变量、方法、构造方法,修饰符、包等信息,这些信息就是用相应的类的实例对象来表示,他们是Field、Method、Contructor、Package等等。
一个类中的每个成员都可以用相应的反射API类的一个实例对象来表示。
三、反射实战
测试Bean:Person.java
1.使用反射获取对象所属类的全路径(包括报名和类名)
测试结果:
ClassName = com.hafiz.zhang.Bean.Person
2.测试使用反射实例化Class类对象
测试结果:
ClassName:com.hafiz.zhang.Bean.Person
ClassName:com.hafiz.zhang.Bean.Person
ClassName:com.hafiz.zhang.Bean.Person
3.测试通过Class类对象实例化其他类
测试结果:
person=Person [id=1, name=Hafiz.Zhang]
4.测试通过Class调用其他类中的构造函数 (也可以通过这种方式通过Class创建其他类的对象)
测试结果:
Person1=Person [id=null, name=null]
Person2=Person [id=1, name=Hafiz.Zhang]
5.测试使用反射获取一个类实现的接口
接口Animal.java
接口Skill.java
实现类:Cat.java
测试类
测试结果:
Cat实现的接口有
com.hafiz.zhang.Bean.Animal
com.hafiz.zhang.Bean.Skill
6.测试通过反射取得指定类的父类
测试结果:SuperClass=class com.hafiz.zhang.Bean.Person
7.测试通过反射获得其他类中的全部构造函数
测试结果:
构造方法:public com.hafiz.zhang.Bean.Person()
构造方法:public com.hafiz.zhang.Bean.Person(java.lang.Integer arg0,java.lang.String arg1)
8. 测试通过反射获取类中的所有方法(包括方法包含的异常)
测试结果:
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.测试通过反射获取类中所有的属性
测试结果:
=========通过反射获取指定类中所有的属性=========
private java.lang.Integer num
private java.lang.String desc
=========通过反射获取指定类实现的接口或者父类中所有的属性=========
public class java.lang.Integer id
private class java.lang.String name
10.测试使用反射调用指定类的方法
测试结果:
cat eat fish
Hello Hafiz.Zhang
11.测试通过反射调用其他类中的setter和getter方法
测试结果:
Desc:null
Desc:测试调用set方法
12.测试通过反射操作属性
测试结果:Desc=this is test demo
13.测试通过反射进行数组操作
测试结果:
数组类型:java.lang.Integer
数组长度:6
数组第一个元素:1
修改之后数组第一个元素:8
=============反射修改数组长度=================
数组长度为:10
8 2 3 4 5 6 null null null null
最近的项目中需要使用到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
package com.hafiz.zhang.Bean; public class Person { public Integer id; private String name; public Person() { } public Person(Integer id, String name) { super(); this.id = id; this.name = name; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "Person [id=" + id + ", name=" + name + "]"; } public void sayHello() throws Exception{ System.out.println("Hello Reflect!"); } }
1.使用反射获取对象所属类的全路径(包括报名和类名)
package com.hafiz.zhang.test; import com.hafiz.zhang.Bean.Person; /** * @author hafiz.Zhang * @Date 2016年5月18日 下午4:28:35 * @Description 测试通过一个对象获取该对象所属于的类的全路径(包括完整包名和类名) */ public class ReflectTest1 { public static void main(String[] args) { Person person = new Person(); System.out.println("ClassName = " + person.getClass().getName()); } }
测试结果:
ClassName = com.hafiz.zhang.Bean.Person
2.测试使用反射实例化Class类对象
package com.hafiz.zhang.test; import com.hafiz.zhang.Bean.Person; /** * @author hafiz.Zhang * @Date 2016年5月18日 下午4:31:36 * @Description 测试获取Class类的三种方式 */ public class ReflectTest2 { public static void main(String[] args) { Class<?> obj1 = null; Class<?> obj2 = null; Class<?> obj3 = null; try { //一般尽量要采用这种方式进行实例化Class类对象 obj1 = (Class<?>) Class.forName("com.hafiz.zhang.Bean.Person"); } catch (ClassNotFoundException e) { e.printStackTrace(); } obj2 = new Person().getClass(); obj3 = Person.class; System.out.println("ClassName:" + obj1.getName()); System.out.println("ClassName:" + obj2.getName()); System.out.println("ClassName:" + obj3.getName()); } }
测试结果:
ClassName:com.hafiz.zhang.Bean.Person
ClassName:com.hafiz.zhang.Bean.Person
ClassName:com.hafiz.zhang.Bean.Person
3.测试通过Class类对象实例化其他类
package com.hafiz.zhang.test; import com.hafiz.zhang.Bean.Person; /** * @author hafiz.Zhang * @Date 2016年5月18日 下午4:38:15 * @Description 测试通过Class类对象实例化其他类 */ public class ReflectTest3 { public static void main(String[] args) { Class<?> clazz = null; try { clazz = Class.forName("com.hafiz.zhang.Bean.Person"); } catch (ClassNotFoundException e) { e.printStackTrace(); } Person person = null; try { person = (Person) clazz.newInstance(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } if(null != person) { person.setId(1); person.setName("Hafiz.Zhang"); System.out.println("person=" + person); }else{ System.out.println("实例化对象失败"); } } }
测试结果:
person=Person [id=1, name=Hafiz.Zhang]
4.测试通过Class调用其他类中的构造函数 (也可以通过这种方式通过Class创建其他类的对象)
package com.hafiz.zhang.test; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import com.hafiz.zhang.Bean.Person; /** * @author hafiz.Zhang * @Date 2016年5月18日 下午4:42:08 * @Description 测试通过Class调用其他类中的构造函数 (也可以通过这种方式通过Class创建其他类的对象) */ public class ReflectTest4 { public static void main(String[] args) { Class<?> clazz = null; try { clazz = Class.forName("com.hafiz.zhang.Bean.Person"); } catch (ClassNotFoundException e) { e.printStackTrace(); } Person p1 = null; Person p2 = null; Constructor<?>[] cs = clazz.getConstructors(); try { p1 = (Person) cs[0].newInstance();//通过无参构造获得对象 p2 = (Person) cs[1].newInstance(1, "Hafiz.Zhang");//通过有参构造获得对象 } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } System.out.println("Person1=" + p1); System.out.println("Person2=" + p2); } }
测试结果:
Person1=Person [id=null, name=null]
Person2=Person [id=1, name=Hafiz.Zhang]
5.测试使用反射获取一个类实现的接口
接口Animal.java
package com.hafiz.zhang.Bean; /** * @author hafiz.Zhang * @Date 2016年5月19日 下午6:13:37 * @Description 动物接口 */ public interface Animal { public abstract void eat(); public abstract void sleep(); }
接口Skill.java
package com.hafiz.zhang.Bean; /** * @author hafiz.Zhang * @Date 2016年5月19日 下午6:14:06 * @Description 技能接口 */ public interface Skill { public abstract void sayMiao(); }
实现类:Cat.java
package com.hafiz.zhang.Bean; public class Cat implements Animal, Skill { private Integer num; private String desc; public Integer getNum() { return num; } public void setNum(Integer num) { this.num = num; } public String getDesc() { return desc; } public void setDesc(String desc) { this.desc = desc; } @Override public void eat() { System.out.println("cat eat fish"); } @Override public void sleep() { System.out.println("cat sleep in the day"); } @Override public void sayMiao() { System.out.println("cat say miao"); } public void sayHello(String name){ System.out.println("Hello " + name); } }
测试类
package com.hafiz.zhang.test; /** * @author hafiz.Zhang * @Date 2016年5月18日 下午4:51:29 * @Description 测试使用反射获取一个类实现的接口 */ public class ReflectTest5 { public static void main(String[] args) { Class<?> clazz = null; try { clazz = Class.forName("com.hafiz.zhang.Bean.Cat"); } catch (ClassNotFoundException e) { e.printStackTrace(); } Class<?>[] interfaces = clazz.getInterfaces(); System.out.println("Cat实现的接口有"); for(Class<?> cl : interfaces) { System.out.println(cl.getName()); } } }
测试结果:
Cat实现的接口有
com.hafiz.zhang.Bean.Animal
com.hafiz.zhang.Bean.Skill
6.测试通过反射取得指定类的父类
package com.hafiz.zhang.test; /** * @author hafiz.Zhang * @Date 2016年5月18日 下午5:03:25 * @Description 测试通过反射取得指定类的父类 */ public class ReflectTest6 { public static void main(String[] args) { Class<?> clazz = null; try { clazz = Class.forName("com.hafiz.zhang.Bean.Cat"); } catch (ClassNotFoundException e) { e.printStackTrace(); } Class<?> superClass = clazz.getSuperclass(); System.out.println("SuperClass=" + superClass); } }
测试结果:SuperClass=class com.hafiz.zhang.Bean.Person
7.测试通过反射获得其他类中的全部构造函数
package com.hafiz.zhang.test; import java.lang.reflect.Constructor; import java.lang.reflect.Modifier; /** * @author hafiz.Zhang * @Date 2016年5月18日 下午5:06:02 * @Description 测试通过反射获得其他类中的全部构造函数 */ public class ReflectTest7 { public static void main(String[] args) { Class<?> clazz = null; try { clazz = Class.forName("com.hafiz.zhang.Bean.Person"); } catch (ClassNotFoundException e) { e.printStackTrace(); } Constructor<?>[] cs = clazz.getConstructors(); //实现方式1 /*for(Constructor<?> item : cs) { System.out.println("构造方法:" + item.getName()); }*/ //实现方式2 for(Constructor<?> item : cs) { System.out.print("构造方法:"); System.out.print(Modifier.toString(item.getModifiers()) + " "); System.out.print(item.getName() + "("); Class<?>[] paramterTypes = item.getParameterTypes(); for(int i = 0; i < paramterTypes.length; i++) { System.out.print(paramterTypes[i].getName() + " arg" + i); if(i < paramterTypes.length-1) { System.out.print(","); } } System.out.println(")"); } } }
测试结果:
构造方法:public com.hafiz.zhang.Bean.Person()
构造方法:public com.hafiz.zhang.Bean.Person(java.lang.Integer arg0,java.lang.String arg1)
8. 测试通过反射获取类中的所有方法(包括方法包含的异常)
package com.hafiz.zhang.test; import java.lang.reflect.Method; import java.lang.reflect.Modifier; /** * @author hafiz.Zhang * @Date 2016年5月18日 下午5:22:51 * @Description 测试通过反射获取类中的所有方法 */ public class ReflectTest8 { public static void main(String[] args) { Class<?> clazz = null; try { clazz = Class.forName("com.hafiz.zhang.Bean.Person"); } catch (ClassNotFoundException e) { e.printStackTrace(); } Method[] methods = clazz.getDeclaredMethods(); for(Method method : methods) { Class<?> returnType = method.getReturnType(); System.out.print(Modifier.toString(method.getModifiers()) + " "); System.out.print(returnType.getName() + " " + method.getName() + "("); Class<?>[] paras = method.getParameterTypes(); for(int i = 0 ; i < paras.length ; i++) { System.out.print(paras[i].getName() + " arg" + i); if(i < paras.length - 1) { System.out.print(","); } } Class<?>[] exces = method.getExceptionTypes(); if(exces.length > 0) { System.out.print(") throws "); for(int j = 0; j < exces.length; j++) { System.out.print(exces[j].getName()); if(j < exces.length - 1) { System.out.print(", "); } } }else{ System.out.print(")"); } System.out.println(); } } }
测试结果:
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.测试通过反射获取类中所有的属性
package com.hafiz.zhang.test; import java.lang.reflect.Field; import java.lang.reflect.Modifier; /** * @author hafiz.Zhang * @Date 2016年5月18日 下午5:38:09 * @Description 测试通过反射获取类中所有的属性 */ public class ReflectTest9 { public static void main(String[] args) { Class<?> clazz = null; try { clazz = Class.forName("com.hafiz.zhang.Bean.Cat"); } catch (ClassNotFoundException e) { e.printStackTrace(); } Field[] fields = clazz.getDeclaredFields(); System.out.println("=========通过反射获取指定类中所有的属性========="); for(Field field : fields) { System.out.println(Modifier.toString(field.getModifiers()) + " " + field.getType().getName() + " " + field.getName()); } System.out.println("=========通过反射获取指定类实现的接口或者父类中所有的属性========="); Field[] fields2 = clazz.getSuperclass().getDeclaredFields(); for(Field item : fields2) { System.out.println(Modifier.toString(item.getModifiers()) + " " + item.getType() + " " + item.getName()); } } }
测试结果:
=========通过反射获取指定类中所有的属性=========
private java.lang.Integer num
private java.lang.String desc
=========通过反射获取指定类实现的接口或者父类中所有的属性=========
public class java.lang.Integer id
private class java.lang.String name
10.测试使用反射调用指定类的方法
package com.hafiz.zhang.test; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; /** * @author hafiz.Zhang * @Date 2016年5月19日 下午3:22:33 * @Description 测试使用反射调用指定类的方法 */ public class ReflectTest10 { public static void main(String[] args) { Class<?> clazz = null; try { clazz = Class.forName("com.hafiz.zhang.Bean.Cat"); } catch (ClassNotFoundException e) { e.printStackTrace(); } try { //调用Cat类中的eat无参方法 Method method = clazz.getMethod("eat"); method.invoke(clazz.newInstance()); //调用Cat类中的sayHello有参方法 Method method2 = clazz.getDeclaredMethod("sayHello", String.class); method2.invoke(clazz.newInstance(), "Hafiz.Zhang"); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (SecurityException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } } }
测试结果:
cat eat fish
Hello Hafiz.Zhang
11.测试通过反射调用其他类中的setter和getter方法
package com.hafiz.zhang.test; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; /** * @author hafiz.Zhang * @Date 2016年5月19日 下午3:29:34 * @Description 测试通过反射调用其他类中的setter和getter方法 */ public class ReflectTest11 { public static void main(String[] args) { Class<?> clazz = null; Object obj = null; try { clazz = Class.forName("com.hafiz.zhang.Bean.Cat"); obj = clazz.newInstance(); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } getter(obj,"Desc"); setter(obj,"Desc","测试调用set方法",String.class); getter(obj,"Desc"); } private static void getter(Object obj, String name) { try { Method method = obj.getClass().getMethod("get"+name); System.out.println(name + ":" + method.invoke(obj)); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (SecurityException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } } private static void setter(Object obj, String name, String desc, Class<?> type) { try { Method method = obj.getClass().getMethod("set" + name, type); method.invoke(obj, desc); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (SecurityException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } } }
测试结果:
Desc:null
Desc:测试调用set方法
12.测试通过反射操作属性
package com.hafiz.zhang.test; import java.lang.reflect.Field; /** * @author hafiz.Zhang * @Date 2016年5月19日 下午3:41:59 * @Description 测试通过反射操作属性 */ public class ReflectTest12 { public static void main(String[] args) { Class<?> clazz = null; Object obj = null; try { clazz = Class.forName("com.hafiz.zhang.Bean.Cat"); obj = clazz.newInstance(); Field field = clazz.getDeclaredField("desc"); //若要设置private属性,需要设置 field.setAccessible(true);//设置成员变量可访问,包括private成员变量(暴力反射),private成员通过这步操作才能被访问 field.set(obj, "this is test demo"); System.out.println("Desc=" + field.get(obj)); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (NoSuchFieldException e) { e.printStackTrace(); } catch (SecurityException e) { e.printStackTrace(); } } }
测试结果:Desc=this is test demo
13.测试通过反射进行数组操作
package com.hafiz.zhang.test; import java.lang.reflect.Array; /** * @author hafiz.Zhang * @Date 2016年5月19日 下午4:52:21 * @Description 测试通过反射进行数组操作 * */ public class ReflectTest13 { public static void main(String[] args) { Integer[] array = {1,2,3,4,5,6}; Class<?> clazz = array.getClass().getComponentType(); System.out.println("数组类型:" + clazz.getName()); System.out.println("数组长度:" + Array.getLength(array)); System.out.println("数组第一个元素:" + Array.get(array, 0)); Array.set(array, 0, 8); System.out.println("修改之后数组第一个元素:" + Array.get(array, 0)); System.out.println("=============反射修改数组长度================="); Integer[] arr2 = (Integer[])changeLength(array, 10); print(arr2); } private static void print(Object obj) { Class<?> clazz = obj.getClass(); if(!clazz.isArray()) { return; } System.out.println("数组长度为:" + Array.getLength(obj)); for(int i = 0; i < Array.getLength(obj); i++){ System.out.print(Array.get(obj, i) + " "); } } public static Object changeLength(Object obj, Integer length){ Class<?> clazz = obj.getClass().getComponentType(); Object newArr = Array.newInstance(clazz, length); Integer len = Array.getLength(obj); System.arraycopy(obj, 0, newArr, 0, len); return newArr; } }
测试结果:
数组类型:java.lang.Integer
数组长度:6
数组第一个元素:1
修改之后数组第一个元素:8
=============反射修改数组长度=================
数组长度为:10
8 2 3 4 5 6 null null null null
相关文章推荐
- Java中的锁
- Java环境变量配置
- Struts2的Result映射
- Java内存模型与volatile
- struts中select标签的使用
- 使用 jsonrpc-for-java 所出現的問題
- Java获取项目当前路径代码
- java解析8583报文55域
- 安装了多个eclipse导致快捷键失效解决办法
- javaoop涉及到登录者 和登录日志的编写
- FileDialog 使用方法---JAVA
- Hadoop 在Windows7操作系统下使用Eclipse来搭建hadoop开发环境
- Java并发编程:Callable、Future和FutureTask
- 使用hbase的java api连接集群超时的问题
- 在Java中怎么定义一个匿名内部类,定义匿名内部类的条件是什么?
- spring 新版本 ExceptionHandler 了解
- 使用eclipse创建java程序可执行jar包
- java Socket实现简单在线聊天(三)
- java Socket实现简单在线聊天(二)
- java Socket实现简单在线聊天(三)