Item 121 023 Note Reflection

Keywords: Java

reflex

Class object

Class class is the root of all reflection

There is a way to get objects of Class classes:

  1. Object.getClass()
  2. class.Class
  3. Class.forName()
package com.laolang.se.fanshe;

import com.laolang.se.fanshe.domain.User;

public class Main {

    public static void main(String[] args) throws ClassNotFoundException {
        User laolang = new User(1001L,"laolang",23);
        User xiaodaima = new User(1001L,"laolang",23);

        Class laolangClazz = laolang.getClass();
        Class xiaodaimaClazz = xiaodaima.getClass();
        System.out.println(laolangClazz == xiaodaimaClazz );

        Class userClazz = User.class;
        System.out.println(userClazz == laolangClazz );

        Class userForName = Class.forName("com.laolang.se.fanshe.domain.User");
        System.out.println(userClazz == userForName );
    }
}

Instantiate objects through Class

  • Call parameterless construction

public T newInstance() throws InstantiationException.IllegalAccessException

In this case, the class must declare a parametric constructor

  • Invoke a parametric build

public Constructor<?>[] getConstructors() throws SecurityException

package com.laolang.se.fanshe;

import com.laolang.se.fanshe.domain.User;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

public class Main {

    public static void main(String[] args) {
        Class&lt;User&gt; userClazz = User.class;

        // Calling parametric-free constructs
        User user = null;
        try {
            user = userClazz.newInstance();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        System.out.println(user);

        // Call parameterized constructs

        // Get all constructions of the current class
        Constructor&lt;?&gt;[] constructors =  userClazz.getConstructors();
        for (Constructor&lt;?&gt; constructor : constructors) {
            System.out.println(constructor.getName());
             Class&lt;?&gt;[] parameterTypes =  constructor.getParameterTypes();
            for (Class&lt;?&gt; parameterType : parameterTypes) {
                System.out.println(parameterType);
            }
        }

        // Gets the specified constructor
        try {
            Constructor&lt;User&gt; constructor = userClazz.getConstructor(Long.class,String.class,Integer.class);
            User laolang = constructor.newInstance(1L,"laolang",23);
            System.out.println(laolang);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }

    }
}

Getting class information through Class classes

  • Get the package where the class is located

public Package getPackage()// Gets the package where a class resides public String getrName()// Get the name

  • Get all the methods in a class

public Method[] getMethods() Public int getModifiers ()// Modifier. toString (moe); // willingness modifier public Class<?> getReturnType() public Class<?>[] getParameterTypes() public Class<?>[] getExceptionTypes() public static String toString(int mod)

  • Get all attributes in a class

public Field[] getFields() public Field[] getDeclaredFields() public Class<?> getType() public int getModifiers() public String getName()

package com.laolang.se.fanshe;

import com.laolang.se.fanshe.domain.User;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

public class Main {

    public static void main(String[] args) {
        Class&lt;User&gt; userClazz = User.class;

        // Package name
        Package packages =  userClazz.getPackage();
        System.out.println(packages.getName());

        // Get the full name of the class
        System.out.println(userClazz.getName());

        System.out.println("--- Get all public methods,Including the parent class-----------------------------");

        // Get method
        // All public methods, including parent methods
        Method[] methods =  userClazz.getMethods();
        for (Method method : methods) {
            System.out.println(method.getName());
        }

        System.out.println("--- Method to get all declarations of the current class-----------------------------------");

        // Method to get all declarations, but excluding parent
        methods = userClazz.getDeclaredMethods();
        for (Method method : methods) {
            System.out.println("Method name:" + method.getName() + "   Modifier:" + Modifier.toString(method.getModifiers()));
        }

        System.out.println("--- Get all attributes-----------------------------------");
        Field[] fields =  userClazz.getDeclaredFields();
        for (Field field : fields) {
            System.out.println(field.getName());
        }

    }
}

Calling properties or methods through Class classes

  • Call methods in classes

Call methods in classes, pass in instantiated objects, and specify parameters

public Object invoke(Object obj, Object... args)

  • Direct invocation of attributes

1. Getting attributes

public Object get(Object obj)

2. Setting Properties

public void set(Object obj, Object value)

3. Make attributes visible to the outside world

public void setAccessible(boolean flag)

package com.laolang.se.fanshe;

import com.laolang.se.fanshe.domain.User;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class Main {

    public static void main(String[] args) {
        Class&lt;User&gt; userClazz = User.class;

        try {
            User user = userClazz.newInstance();
            System.out.println(user);
            // Calling public methods
            Method method = userClazz.getMethod("setName", String.class);
            method.invoke(user,"laolang");
            System.out.println(user);
            // Calling public methods
            method = userClazz.getDeclaredMethod("say");
            // Skip the checking of modifiers
            method.setAccessible(true);
            method.invoke(user);
            // Open modifier checking
            method.setAccessible(false);
            //method.invoke(user);

        }  catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }

    }
}

Dynamic proxy

The so-called dynamic proxy, that is, through the proxy class: Proxy proxy, the interface and the implementation class can not be directly linked, but can achieve dynamic association at runtime.

Java Dynamic Proxy mainly uses two classes in java.lang.reflect package

  • InvocationHandler class

public Object invoke(Object obj, Method method, Object[] obs)

The first parameter obj refers to the proxy class, method is the proxy method, and obs refers to the group of parameters of the proxy method. This method is implemented by proxy classes

  • Class Proxy
protected Proxy(InvocationHandler h);
static Class getProxyClass(ClassLoader loader, Class[] interfaces);
static Object newProxyInstance(ClassLoader loader, Class[] interfaces , InvocationHandler h );

Dynamic proxy actually generates classes at runtime, so we have to provide a set of interfaces, and then tell him that classes have implemented these interfaces, and when Proxy is generated, we have to provide him with a handler to take over the actual work.

user

package com.laolang.se.fanshe.domain;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Surrogate class
 */
public class User  implements Subject{

    private static final Logger log = LoggerFactory.getLogger(User.class);

    public User() {
        log.info("Calling a parametric constructor");
    }

    public User(Long id, String name, Integer age) {
        log.info("Calling a parametric constructor");
        this.id = id;
        this.name = name;
        this.age = age;
    }

    private String say(){
        return name;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    private Long id;

    private String name;

    private Integer age;

    @Override
    public void miai() {
        System.out.println("In a blind date...");

    }
}

subject

package com.laolang.se.fanshe.domain;

/**
 * Subject Interface to Agent
 */
public interface Subject {

    /**
     * Blind date
     */
    public void miai();
}

DynaProxy

package com.laolang.se.fanshe.domain;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

/**
 * Dynamic proxy class
 */
public class DynaProxy implements InvocationHandler {

    public DynaProxy(Object target) {
        this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object o = null;
        before();
        // Calling business methods
        o = method.invoke(target,args);
        after();
        return o;
    }

    /**
     * What you did before you went on a blind date
     */
    private void before(){
        System.out.println("Matching objects for agents");
    }

    /**
     * What to do after a blind date
     */
    private void after(){
        System.out.println("The blind date ended");
    }

    /**
     * Proxy object
     */
    private Object target;
}

Main

package com.laolang.se.fanshe;

import com.laolang.se.fanshe.domain.DynaProxy;
import com.laolang.se.fanshe.domain.Subject;
import com.laolang.se.fanshe.domain.User;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class Main {

    public static void main(String[] args) {
        User user = new User(1L,"Wolf",23);
        DynaProxy dynaProxy = new DynaProxy(user);
        // Dynamic generation of proxy objects (class loader, proxy interface, Invocation Handler)
        Subject subject = (Subject) Proxy.newProxyInstance(user.getClass().getClassLoader(), user.getClass().getInterfaces(), dynaProxy);
        subject.miai();

    }
}

Posted by bskauge on Fri, 19 Apr 2019 09:27:34 -0700