Java反射机制
Posted one-reader
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java反射机制相关的知识,希望对你有一定的参考价值。
一、什么是反射?
Java反射是Java被视为动态(或准动态)语言的一个关键性质。这个机制允许程序在运行时透过Reflection APIs取得任何一个已知名称的class的内部信息,包括其modifiers(诸如public, static 等)、superclass(例如Object)、实现之interfaces(例如Cloneable),也包括fields和methods的所有信息,并可于运行时改变fields内容或唤起methods。
简单来说,就是java反射机制可以在运行阶段,基于编译阶段的class对象,动态的创建对象,获取类的完整结构。
二、反射的使用
定义一个类:
public class ReflectionDemo
public String username;
private Integer password ;
public ReflectionDemo()
public ReflectionDemo(String name)
System.out.println(name);
public void say()
System.out.println("hello!");
public void talk(String name, Integer age)
System.out.println(name + "今年:" + age + "岁!");
获取类型
/**
* 获取类对象的三种方式
*/
//1.通过对象的getClass()方法获取
ReflectionDemo rd = new ReflectionDemo();
Class<? extends ReflectionDemo> aClass = rd.getClass();
System.out.println("通过对象的getClass()方法获取:"+aClass);
//2.通过类名的class
Class<? extends ReflectionDemo> aClass1 = ReflectionDemo.class;
System.out.println("通过类名的class: "+aClass1);
//3.通过Class.forName()
try
Class<?> aClass2 = Class.forName("com.my.reflection.ReflectionDemo");
System.out.println("Class.forName():"+aClass2);
catch (ClassNotFoundException e)
e.printStackTrace();
运行结果:
通过对象的getClass()方法获取:class com.my.reflection.ReflectionDemo
通过类名的class: class com.my.reflection.ReflectionDemo
Class.forName():class com.my.reflection.ReflectionDemo
获取属性
/**
* 反射 获取成员变量
* Field getField(String name) 根据变量名,返回一个具体的具有public属性的成员变量
* Field[] getFields() 返回具有public属性的成员变量的数组
* Field getDeclaredField(String name) 根据变量名,返回一个成员变量(不分public和非public属性)
* Field[] getDelcaredFields() 返回所有成员变量组成的数组(不分public和非public属性)
*/
Class class4 = null;
try
//获取类对象
class4 = Class.forName("com.my.reflection.ReflectionDemo");
//获取属性
Field field1 = class4.getField("username");
System.out.println("field1=" + field1.getName());
Field field2 = class4.getDeclaredField("password");
System.out.println("field2=" + field2.getName());
System.out.println("*******************");
// 使用getFields获取属性
Field[] fields = class4.getFields();
for (Field f : fields)
System.out.println(f);
System.out.println("*******************");
// 使用getDeclaredFields获取属性
fields = class4.getDeclaredFields();
for (Field f : fields)
System.out.println(f);
运行结果:
field1=username
field2=password
*******************
public java.lang.String com.my.reflection.ReflectionDemo.username
*******************
public java.lang.String com.my.reflection.ReflectionDemo.username
private java.lang.Integer com.my.reflection.ReflectionDemo.password
获取类的方法
/**
* 反射 调用 对象方法
* Method getMethod(String name, Class[] params) 根据方法名和参数,返回一个具体的具有public属性的方法
* Method[] getMethods() 返回所有具有public属性的方法数组
* Method getDeclaredMethod(String name, Class[] params) 根据方法名和参数,返回一个具体的方法(不分public和非public属性)
* Method[] getDeclaredMethods() 返回该类中的所有的方法数组(不分public和非public属性)
*/
Class class3 = null;
try
class3 = Class.forName("com.my.reflection.ReflectionDemo");
Method method = class3.getMethod("talk", String.class,Integer.class);
Object object = class3.newInstance();
method.invoke(object, "老王",18);
catch (ClassNotFoundException e)
e.printStackTrace();
catch (NoSuchMethodException e)
e.printStackTrace();
catch (IllegalAccessException e)
e.printStackTrace();
catch (InstantiationException e)
e.printStackTrace();
catch (InvocationTargetException e)
e.printStackTrace();
运行结果:
老王今年:18岁!
获取类的Constructor
/**
* 反射通过无惨构造实例对象
*/
Class class1 = null;
try
class1 = Class.forName("com.my.reflection.ReflectionDemo");
Object object = class1.newInstance();
ReflectionDemo reflectionDemo = (ReflectionDemo) object;
reflectionDemo.say();
catch (ClassNotFoundException e)
e.printStackTrace();
catch (IllegalAccessException e)
e.printStackTrace();
catch (InstantiationException e)
e.printStackTrace();
/**
* 反射通过构造实例对象
* Constructor getConstructor(Class[] params)根据构造函数的参数,返回一个具体的具有public属性的构造函数
* Constructor getConstructors() 返回所有具有public属性的构造函数数组
* Constructor getDeclaredConstructor(Class[] params) 根据构造函数的参数,返回一个具体的构造函数(不分public和非public属性)
* Constructor getDeclaredConstructors() 返回该类中所有的构造函数数组(不分public和非public属性)
*/
Class class2 = null;
try
class2 = Class.forName("com.my.reflection.ReflectionDemo");
Constructor constructor = class2.getConstructor(String.class);
Object object = constructor.newInstance("abc");
ReflectionDemo reflectionDemo = (ReflectionDemo) object;
reflectionDemo.say();
catch (ClassNotFoundException e)
e.printStackTrace();
catch (NoSuchMethodException e)
e.printStackTrace();
catch (InstantiationException e)
e.printStackTrace();
catch (IllegalAccessException e)
e.printStackTrace();
catch (InvocationTargetException e)
e.printStackTrace();
运行结果
hello!
abc
hello!
动态Proxy
java.lang.reflect.Proxy
Proxy 提供用于创建动态代理类和实例的静态方法,它还是由这些方法创建的所有动态代理类的超类
InvocationHandler
是代理实例的调用处理程序 实现的接口,每个代理实例都具有一个关联的调用处理程序。对代理实例调用方法时,将对方法调用进行编码并将其指派到它的调用处理程序的 invoke 方法。
UserService接口
public interface UserService
String getName(String name);
UserService实现
public class UserServiceImpl implements UserService
public String getName(String name)
System.out.println(name);
return "getName";
MyInvocationHandler代理类
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
/**
* jdk动态代理
* @author onereader
*/
public class MyInvocationHandler implements InvocationHandler
//目标对象
private Object target;
public MyInvocationHandler()
super();
public MyInvocationHandler(Object target)
super();
this.target = target;
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable
if (method.getName().equals("getName"))
System.out.println("++++++before " + method.getName() + "++++++");
Object result = method.invoke(target, args);
System.out.println("++++++after " + method.getName() + "++++++");
return result;
else
Object result = method.invoke(target, args);
return result;
MainTest 类
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
public class MainTest
public static void main(String[] args)
UserService userService = new UserServiceImpl();
InvocationHandler invoke = new MyInvocationHandler(userService);
UserService userServiceProxy = (UserService) Proxy.newProxyInstance(userService.getClass().getClassLoader(),
userService.getClass().getInterfaces(), invoke);
System.out.println(userServiceProxy.getName("123"));
运行结果:
++++++before getName++++++
123
++++++after getName++++++
getName
三、总结
对于反射,简单来说就是可以再运行时,可以获取到这个类的完整信息。并且创建一个满足自己需要的对象,进行操作。总的来说,学会后使用起来真心很方便~~~ 至于反射的不好地方,我这里不熬诉了,有兴趣自行百度学习~
以上是关于Java反射机制的主要内容,如果未能解决你的问题,请参考以下文章