Java 反射机制,
分享于 点击 4063 次 点评:147
Java 反射机制,
反射的概念
1、反射被看作是动态语言的关键,反射机制允许程序在执行期间借助Reflect的API取得任何类的内部信息以及操作内部属性和方法。
Class类
1、Class类被定义为反射的源头。在Object类中定义了public final Class getClass(){}这个方法来获取运行时类Class,这个Class可以保存类的运行时信息。
2、有了反射,可以通过反射创建一个对象,并调用其中的结构。一般来说,有三种方法来获取对象的运行时类Class:
先建立一个User类,这个User 定义一些成员变量,成员方法等
<span >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 >Class clazz=User.class;</span>
b、通过运行时类对象
<span >User u=new User();
Class clazz=u.getClass();</span>
c、通过Class的静态方法
<span >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 >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 >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{
@Override
public void action() {
System.out.println("我是被代理的对象类,被代理执行");
}
}
//接口
interface ClothFactory {
public void productCloth();
}
//被代理类
class NikeClothFactory implements ClothFactory{
@Override
public 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方法的调用
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
//method方法的返回值是returnVal
Object 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>
相关文章
- 暂无相关文章
用户点评