Java 反射机制

来源:互联网 发布:如何做淘宝网店的生意 编辑:程序博客网 时间:2024/06/08 14:53

反射的概念

1、反射被看作是动态语言的关键,反射机制允许程序在执行期间借助Reflect的API取得任何类的内部信息以及操作内部属性和方法。

Class类

1、Class类被定义为反射的源头。在Object类中定义了public final Class getClass(){}这个方法来获取运行时类Class,这个Class可以保存类的运行时信息。

2、有了反射,可以通过反射创建一个对象,并调用其中的结构。一般来说,有三种方法来获取对象的运行时类Class

先建立一个User类,这个User 定义一些成员变量,成员方法等

<span style="font-size:14px;">package com.reflect;public class User {  private String userName;  private int age;  public User() {}  public User(String userName, int age) {    super();    this.userName = userName;    this.age = age; }  public String doWork(String work){      return "the User is working with"+work;  }}</span>
下面就是创建运行时类的三种方法

a、调用运行时类的本身的Class属性

<span style="font-size:14px;">Class clazz=User.class;</span>

b、通过运行时类对象

<span style="font-size:14px;">User u=new User();Class clazz=u.getClass();</span>

c、通过Class的静态方法

<span style="font-size:14px;">Class clazz=Class.forName("com.reflect.User");</span>
当创建了运行时类Class以后,可以通过反射来获取类的信息,以及调用类的方法。

java.lang.reflect

1、这个包是用来分析类的相关信息,可以通过这个包里面的Field、Method、Constructor这三个类来实现对类信息的动态捕获。

2、java.lang.reflect.Field使用方法,类里的方法主要是用来获取类的成员变量如下例子:

package com.reflect;import java.io.ObjectInputStream.GetField;import java.lang.reflect.Field;public class reflect_demo {public static void main(String[] args) {Class clazz=User.class;Field [] fields=clazz.getDeclaredFields();//获取声明的所有属性//Field fields=clazz.getDeclaredField("age");//获取声明为age的属性//Field [] fields=clazz.getFields();//获取为访问权限为public的属性//clazz.getField("age");//获取访问权限为public且声明为age的属性for (Field field : fields) {String name=field.getName();//获取属性名int modify=field.getModifiers();}}}

3、java.lang.reflect.Method使用方法,主要是用来获取类的成员方法

package com.reflect;import java.lang.reflect.Method;public class reflect_demo {public static void main(String[] args) throws Exception{Class clazz=User.class;Method [] methods=clazz.getMethods();//获取所有的public方法//Method  method=clazz.getMethod("work");//Method [] methods=clazz.getDeclaredMethods();//获取类声明的所有方法//Method  method=clazz.getDeclaredMethod("work");for (Method method : methods) {String name=method.getName();//方法名String returnType=method.getReturnType().getName();//方法返回类型Class [] params=method.getParameterTypes();//方法形参列表int modify=method.getModifiers();//方法权限修饰    Class [] exceptions=method.getExceptionTypes();//抛出异常列表}//动态调用一个方法Method method=clazz.getDeclaredMethod("doWork", String.class);Object result=method.invoke(clazz.newInstance(), "teacher");}}
上面对于Method类的方法只列举了一些重要常用的,其它方法可以参考JDK API查看

4、java.lang.reflect.Constructor使用方法

<span style="font-size:14px;">package com.reflect;import java.lang.reflect.Constructor;import java.lang.reflect.Method;public class reflect_demo {public static void main(String[] args) throws Exception{Class clazz=User.class;Constructor [] constructors=clazz.getConstructors();//获取声明为public的构造函数//Constructor [] constructor=clazz.getDeclaredConstructors();//获取所有的构造函数}}</span>
Constructor的其它方法与Method类的方法有些类似此外就不再详细叙述,有兴趣的可以参考JDK API

反射的应用

反射的动态语言的关键,java中的一个重要的动态代理就是用反射来实现的,下面就是动态代理的简单实现过程

<span style="font-size:14px;">package com.reflect;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;//动态代理的使用,反射是动态语言的关键interface Subject{public void action();}//被代理类class RealSubject implements Subject{@Overridepublic void action() {System.out.println("我是被代理的对象类,被代理执行");}}//接口interface ClothFactory {public void productCloth();}//被代理类class NikeClothFactory implements ClothFactory{@Overridepublic void productCloth() {System.out.println("Nike工厂生产一批衣服");}}class MyInvocationHandler implements InvocationHandler{Object obj;//实现了接口被代理类的对象的声明//给被代理类的对象实例化,返回一个代理类的对象public Object blind(Object obj){this.obj=obj;return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), this);}//当通过代理类的对象发起对被重写的方法调用时,都会转换为对如下的invoke方法的调用@Overridepublic Object invoke(Object proxy, Method method, Object[] args)throws Throwable {//method方法的返回值是returnValObject returnVal= method.invoke(obj, args);return returnVal;}}public class TestProxy {public static void main(String[] args) {//1、被代理类的对象、RealSubject real=new RealSubject();//2、创建一个实现了InvocationHandler接口的类对象MyInvocationHandler handler=new MyInvocationHandler();//3、调用blind方法,动态的返回一个同样实现了real所在类实现的接口的代理类的对象 Object obj=handler.blind(real);Subject sub=(Subject)obj;//此时sub就是代理类对象//4、sub.action();//转到对InvocationHandler接口的实现类Invoke方法的调用 //NikeClothFactory nike=new NikeClothFactory();//创建被代理对象ClothFactory proxyCloth=(ClothFactory) handler.blind(nike);proxyCloth.productCloth();}}</span>



0 0
原创粉丝点击