Use Java reflection to see which one is enough

## 1. What is reflected
reflection (Reflection) allows programs running on the JVM detect and modify runtime behavior.
## 2. Why do we need reflection
reflection allows us to:

  • Detection target type at runtime;
  • A class object is dynamically constructed;
  • Properties and methods of detecting the class;
  • Any method calls the object;
  • Modify constructors, methods, visibility attribute;
  • And other.

## 3, Java Why support reflection
still has Java run-time type information, which contains all the class: what class it what field, what methods, what each level of protection and so on, there is this class relies on. In Java, the class information is stored in the form of an object, the object is a meta-objects, their type is Class. Armed with this information, whether it is dynamically created object or calling certain methods are easy. In C ++, through RTTI (runtime type identification), we can know some information about the class, but why did not C ++, Reflection, due to the type of information is not complete. RTTI The name itself tells us, C ++ type information is used to identify the type, so it does not require other additional information. Not C ++ can not do this, but C ++ does not want to give users additional burden. There are income, will inevitably be lost, therefore, C ++ abandoned the meta-object.
## 4, how to use the reflection
to be specified class ReflectionDemo

package com.xiuxiuing;

public class ReflectionDemo {
   public static String tag = "demo";
    private String mName;
    private static ReflectionDemo instance;

    public ReflectionDemo() {

    }

    public ReflectionDemo(String name) {
        this.mName = name;
    }

    public static ReflectionDemo getInstance() {
        if (instance == null) {
            instance = new ReflectionDemo();
        }
        return instance;
    }

    public String getName() {
        return mName;
    }

    public void setName(String mName) {
        this.mName = mName;
    }
}
  • Get the class
Class cls = Class.forName("com.xiuxiuing.ReflectionDemo");  
  • Gets an instance of the class
Object o = cls.newInstance();
  • There are instances of the class reference configuration acquisition
Constructor<?> csr = cls.getConstructor(String.class);
Object obj = csr.newInstance("张三");
  • By way of example a single embodiment of the acquired class
Method getInstance = cls.getMethod("getInstance");
Object ob = getInstance.invoke(null);
  • Modify the value of the property
Field fieldName = cls.getDeclaredField("mName");
fieldName.setAccessible(true);
fieldName.set(obj, "李四");
  • There parametric method calls the class
Method setMet = cls.getMethod("setName", String.class);
setMet.invoke(obj, "王二");
  • No reference method calls the class
Method getMet = cls.getMethod("getName");
String name = (String) getMet.invoke(obj);
  • Values ​​of static variables modified class
Field tagField = cls.getField("tag");
tagField.set(obj, "reflec");
  • Values ​​of static variables get the class
String tag = (String) tagField.get(null);

## 5, Java dynamic proxy
in java dynamic proxy mechanism, there are two important classes or interfaces, one InvocationHandler (Interface), the other is Proxy (Class), which is a class and interfaces to achieve our dynamic proxy that must be used.
We will talk through examples how to use Java dynamic proxies:

  • Subject to define a type of interface
public interface Subject {
    public void rent();
    public void hello(String str);
}
  • RealSubject define a class that implements this interface
public class RealSubject implements Subject {
    @Override
    public void rent() {
        System.out.println("I want to rent my house");
    }
    
    @Override
    public void hello(String str) {
        System.out.println("hello: " + str);
    }
}
  • DynamicProxy define a dynamic proxy class that implements this interface InvocationHandler
public class DynamicProxy implements InvocationHandler {
    // 这个就是我们要代理的真实对象
    private Object subject;
    
    // 构造方法,给我们要代理的真实对象赋初值
    public DynamicProxy(Object subject) {
        this.subject = subject;
    }
    
    @Override
    public Object invoke(Object object, Method method, Object[] args)
            throws Throwable {
        // 在代理真实对象前我们可以添加一些自己的操作
        System.out.println("before rent house");
        
        System.out.println("Method:" + method);
        
        // 当代理对象调用真实对象的方法时,其会自动的跳转到代理对象关联的handler对象的invoke方法来进行调用
        method.invoke(subject, args);
        
        // 在代理真实对象后我们也可以添加一些自己的操作
        System.out.println("after rent house");
        
        return null;
    }

}
  • Take a look at our Client class
public class Client {
    public static void main(String[] args) {
        // 我们要代理的真实对象
        Subject realSubject = new RealSubject();

        // 我们要代理哪个真实对象,就将该对象传进去,最后是通过该真实对象来调用其方法的
        InvocationHandler handler = new DynamicProxy(realSubject);

        /*
         * 通过Proxy的newProxyInstance方法来创建我们的代理对象,我们来看看其三个参数
         * 第一个参数 handler.getClass().getClassLoader() ,我们这里使用handler这个类的ClassLoader对象来加载我们的代理对象
         * 第二个参数realSubject.getClass().getInterfaces(),我们这里为代理对象提供的接口是真实对象所实行的接口,表示我要代理的是该真实对象,这样我就能调用这组接口中的方法了
         * 第三个参数handler, 我们这里将这个代理对象关联到了上方的 InvocationHandler 这个对象上
         */
        Subject subject = (Subject)Proxy.newProxyInstance(handler.getClass().getClassLoader(), realSubject
                .getClass().getInterfaces(), handler);
        
        System.out.println(subject.getClass().getName());
        subject.rent();
        subject.hello("world");
    }
}
  • Console output
$Proxy0

before rent house
Method:public abstract void com.xiaoluo.dynamicproxy.Subject.rent()
I want to rent my house
after rent house

before rent house
Method:public abstract void com.xiaoluo.dynamicproxy.Subject.hello(java.lang.String)
hello: world
after rent house

We first take a look at $ Proxy0 this thing, we see that this thing is System.out.println (subject.getClass () getName ().); This statement printed out, so why should we return this proxy object the class name is this?

Subject subject = (Subject)Proxy.newProxyInstance(handler.getClass().getClassLoader(), realSubject
                .getClass().getInterfaces(), handler);

I thought it might return this proxy object will be subject Subject type, or InvocationHandler object, the result is not the first we explain why we are here to convert it into an object of type Subject? The reason is that on the second parameter newProxyInstance this method, we give the proxy object provides a set of what the interface, the proxy, then I will achieve this set of interfaces, of course, this time we can use this proxy object mandatory conversion this set of interfaces is an arbitrary one, since the Subject the interface type, it can be converted to a type Subject.

At the same time we must remember, by Proxy.newProxyInstance proxy object is an object created dynamically generated jvm to run, it is not our InvocationHandler type, not our type defined set of interfaces, but is in the running a dynamically generated objects, and such forms are named, beginning $, Proxy is, the last number indicates a reference object.

Then we take a look at these two

subject.rent();
subject.hello("world");

Here is a method that is invoked by the interface proxy object to achieve in this time the program will jump to invoke the method handler is associated by this proxy object to the execution to go, and our object is the handler has received a RealSubject types of parameters, I want to represent this agency is the real object, so in this case will call to invoke the method handler in the execution:

public Object invoke(Object object, Method method, Object[] args)
            throws Throwable {
        // 在代理真实对象前我们可以添加一些自己的操作
        System.out.println("before rent house");
        
        System.out.println("Method:" + method);
        
        // 当代理对象调用真实对象的方法时,其会自动的跳转到代理对象关联的handler对象的invoke方法来进行调用
        method.invoke(subject, args);
        
        // 在代理真实对象后我们也可以添加一些自己的操作
        System.out.println("after rent house");
        
        return null;
    }

We see that in real time to call the real object through a proxy object method, we can add some of their own operations before and after the process, and we see our target of this method is such that

public abstract void com.xiaoluo.dynamicproxy.Subject.rent()

public abstract void com.xiaoluo.dynamicproxy.Subject.hello(java.lang.String)

Our method is just two Subject interface, which also proved that when I call the method through a proxy object from its actual commission is to invoke the method associated with the handler object to call, not yourself true calling, but by the way agents to call.
## 6, how to improve the efficiency of reflection

  1. Try not to getMethods () and then traverse the screening directly with getMethod (methodName) according to the method name acquisition method.
  2. Many times as needed to dynamically create an instance of the class, when there is a cache wording will not be much faster than the cache.

Welcome to sweep the code number of public attention, better communication

Published 115 original articles · won praise 67 · Views 100,000 +

Guess you like

Origin blog.csdn.net/meifannao789456/article/details/100079250