关于Java反射的总结
Java的反射应用场景很多,但是每次都感觉有些懵,故作此文作为总结。
反射是什么
首先,反射,那肯定有正的吧。
正向
Man man=new Man();
man.sayHello();
反射
Class clazz = Man.class.getClass(); //获取Class类
Man man = (Man) clazz.newInstance(); // 用Class类创建实例
man.sayHello(); //调用实例方法
这边难免会联想到Spring的IOC了,其实Spring的IOC设计思想也是用到了反射的机制,使用反射在BeanFactory中生成对象。
反射什么用
当我们很明确需要将Man类实例化,自然可以用new的方式来创建对象实例。但是在某些场景并不明确new的对象是什么的时候,我们或许可以用多态的方式进行处理。
class abstract Human{}
class Man extends Human{}
class Woman extends Human{}
Human human1=new Man();
Human human2=new Woman();
用反射的方式也可以处理
Class clazz = Man.class.getClass(); //获取Class类
Man man = (Man) clazz.newInstance(); // 用Class类创建实例
但是仅仅用来创建对象,那反射也太没用了。学过JVM的都知道Class对象为class文件经过加载、链接和初始化的过程作为一个对象而存在,里面含有类的元信息。
-
获得构造方法
Class clazz = Man.class.getClass(); Constructor constructor = clazz.getConstructor(); constructor.newInstance(); // 通过构造器创建实例也是一种利用反射机制创建实例的手段 -
获得某个方法并且使用该方法
Class clazz = Man.class.getClass(); Man man = (Man) clazz.newInstance(); Method sayHelloMethod = clazz.getMethod("sayHello", int.class); //获取方法信息,通过指定的方法名和返回类型 sayHelloMethod.invoke(man,...方法参数); -
获取字段
Field field=clazz.getField("name");
看到了现在终于明白了吧?其实类的反射机制就是通过Class为入口,使用Class来灵活的创建、使用对象。可以通过传递类的全路径、方法名作为调用某些方法的动态控制。
获取Class的方式
Class clazz=String.class
Class clazz=Class.forName("java.lang.String");
Class class=String.getClass();
应用场景
Spring的IOC机制
class UserFactory{
public static UserDao getDao(){
String classValue=...//来自于xml文件的解析
Class clazz=Class.forName(classValue);//通过反射创建对象
return (UserDao)class.newInstance();
}
}
JDK动态代理
接口
public interface ManIntereface {
public void sayHello();
}
目标类
public class Man implements ManIntereface{
public void sayHello(){
System.out.println("hello world");
}
}
代理
public class HelloProxy implements InvocationHandler {
private Object subject;
public HelloProxy(Object object) {
this.subject = object;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("方法调用前置处理");
method.invoke(subject, args);
System.out.println("方法调用后置处理");
return null;
}
}
调用测试
public class Client {
public static void main(String[] args) {
Man man = new Man();
InvocationHandler handler = new ManProxy(man);
ManIntereface manIntereface = (ManIntereface) Proxy
.newProxyInstance(handler.getClass().getClassLoader(),
man.getClass().getInterfaces(),
handler);
manIntereface.sayHello();
}
}
浙公网安备 33010602011771号