Foreword # #

A few days ago, I was studying a Router (routing mode) Demo, which was written very well. I happened to find reflection used in it. I thought I should take it out and write something about it.

So it was decided that the ultimate goal of this series was to customize the awesome database framework: to create a core Demo that mimicked the latest popular database framework patterns with annotations and reflections (just look at the core ideas, with minimal concern for code robustness).

When I first got to know Java, I was very disgusted with reflection. A lot of code I didn’t know about destroyed the original design structure. After a long time of code development, I found it was actually very cute.

One hundred people have one hundred ideas, so others design may be something to do with your design ideas are not the same, all had to use reflection to reach own purpose, a lot of people say that reflection is actually a very consume resources, no use unless it is, after this we can actually test.

On the Internet to find a lot of information, write are great, feel I write things certainly no one else to write good, I directly find a I think the most concise and clear reprinted.

# # text

The original blog http://www.cnblogs.com/lzq198754/p/5780331.html

What is the reflex mechanism

Reflection mechanism is in the running state, for any class, can know all the attributes and methods of the class; For any object, you can call any of its methods and properties; This ability to dynamically retrieve information and invoke methods on objects is called the Reflection mechanism of the Java language. 2 What can reflex mechanisms do

The reflection mechanism provides the following functions:

Determine the class of any object at run time; Construct an object of any class at runtime; Determine which member variables and methods any class has at run time. Call a method of any object at runtime; Generate dynamic proxies.Copy the code

The reflection API gets the full package name and class name from an object

package net.xsoftlab.baike;
public class TestReflect {
    public static void main(String[] args) throws Exception {
        TestReflect testReflect = new TestReflect();
        System.out.println(testReflect.getClass().getName()); / / the result net. Xsoftlab. Baike. TestReflect}}Copy the code

Instantiate the Class object

package net.xsoftlab.baike; public class TestReflect { public static void main(String[] args) throws Exception { Class<? > class1 = null; Class<? > class2 = null; Class<? > class3 = null; Class1 = class.forname ("net.xsoftlab.baike.TestReflect");
        class2 = new TestReflect().getClass();
        class3 = TestReflect.class;
        System.out.println("Class Name" + class1.getName());
        System.out.println("Class Name" + class2.getName());
        System.out.println("Class Name"+ class3.getName()); }}Copy the code

Gets the interface between an object’s parent class and its implementation

package net.xsoftlab.baike; import java.io.Serializable; public class TestReflect implements Serializable { private static final long serialVersionUID = -2862585049955236662L; public static void main(String[] args) throws Exception { Class<? > clazz = Class.forName("net.xsoftlab.baike.TestReflect"); // Get the parent Class<? > parentClass = clazz.getSuperclass(); System.out.println("The parent of clazz is:"+ parentClass.getName()); // Clazz's parent Class is java.lang.Object. > intes[] = clazz.getInterfaces(); System.out.println(Clazz implements the following interfaces:);
        for (int i = 0; i < intes.length; i++) {
            System.out.println((i + 1) + ":"+ intes[i].getName()); // 1: java.io.Serializable}}Copy the code

Get all constructors in a class – see the example below for instantiating an object of a class through reflection

package net.xsoftlab.baike; import java.lang.reflect.Constructor; public class TestReflect { public static void main(String[] args) throws Exception { Class<? > class1 = null; class1 = Class.forName("net.xsoftlab.baike.User"); // The first method, instantiating the default constructor, callssetAssignment User User = (User) class.newinstance (); user.setAge(20); user.setName("Rollen"); System.out.println(user); User [age=20, name=Rollen] // The second way to get all constructors is to assign Constructor<? > cons[] = class1.getConstructors(); // View the parameters required by each constructorfor(int i = 0; i < cons.length; i++) { Class<? > clazzs[] = cons[i].getParameterTypes(); System.out.print("cons[" + i + "] (");
            for (int j = 0; j < clazzs.length; j++) {
                if (j == clazzs.length - 1)
                    System.out.print(clazzs[j].getName());
                else
                    System.out.print(clazzs[j].getName() + ",");
            }
            System.out.println(")"); } // result // cons[0] (java.lang.string) // cons[1] (int, java.lang.string) // cons[2] () user = (user) cons[0].newinstance ()"Rollen"); System.out.println(user); // Result User [age=0, name=Rollen] User = (User) cons[1]. NewInstance (20,"Rollen"); System.out.println(user); User [age=20, name=Rollen]}} class User {private int age; private String name; publicUser() {
        super();
    }
    public User(String name) {
        super();
        this.name = name;
    }
    public User(int age, String name) {
        super();
        this.age = age;
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    @Override
    public String toString() {
        return "User [age=" + age + ", name=" + name + "]"; }}Copy the code

Gets all attributes of a class

package net.xsoftlab.baike; import java.io.Serializable; import java.lang.reflect.Field; import java.lang.reflect.Modifier; public class TestReflect implements Serializable { private static final long serialVersionUID = -2862585049955236662L; public static void main(String[] args) throws Exception { Class<? > clazz = Class.forName("net.xsoftlab.baike.TestReflect");
        System.out.println("=============== Attributes of this class ==============="); Field[] Field = clazz.getDeclaredFields();for(int i = 0; i < field.length; I ++) {int mo = field[I].getMODIfiers (); String priv = Modifier.toString(mo); // Attribute type Class<? >type = field[i].getType();
            System.out.println(priv + "" + type.getName() + "" + field[i].getName() + ";");
        }
         
        System.out.println("========== implemented interface or superclass property =========="); Field[] filed1 = clazz.getFields();for(int j = 0; j < filed1.length; J ++) {// permission modifier int mo = filed1[j]. String priv = Modifier.toString(mo); // Attribute type Class<? >type = filed1[j].getType();
            System.out.println(priv + "" + type.getName() + "" + filed1[j].getName() + ";"); }}}Copy the code

Gets all the methods of a class

package net.xsoftlab.baike; import java.io.Serializable; import java.lang.reflect.Method; import java.lang.reflect.Modifier; public class TestReflect implements Serializable { private static final long serialVersionUID = -2862585049955236662L; public static void main(String[] args) throws Exception { Class<? > clazz = Class.forName("net.xsoftlab.baike.TestReflect");
        Method method[] = clazz.getMethods();
        for(int i = 0; i < method.length; ++i) { Class<? >returnType = method[i].getReturnType(); Class<? > para[] = method[i].getParameterTypes(); int temp = method[i].getModifiers(); System.out.print(Modifier.toString(temp) +"");
            System.out.print(returnType.getName() + "");
            System.out.print(method[i].getName() + "");
            System.out.print("(");
            for (int j = 0; j < para.length; ++j) {
                System.out.print(para[j].getName() + "" + "arg" + j);
                if (j < para.length - 1) {
                    System.out.print(","); } } Class<? > exce[] = method[i].getExceptionTypes();if (exce.length > 0) {
                System.out.print(") throws ");
                for (int k = 0; k < exce.length; ++k) {
                    System.out.print(exce[k].getName() + "");
                    if (k < exce.length - 1) {
                        System.out.print(","); }}}else {
                System.out.print(")"); } System.out.println(); }}}Copy the code

Call a method of a class through reflection

package net.xsoftlab.baike; import java.lang.reflect.Method; public class TestReflect { public static void main(String[] args) throws Exception { Class<? > clazz = Class.forName("net.xsoftlab.baike.TestReflect"); Method reflect1 = clazz.getMethod("reflect1"); method.invoke(clazz.newInstance()); // Call TestReflect reflect2 method method = clazz.getMethod("reflect2", int.class, String.class);
        method.invoke(clazz.newInstance(), 20, "Zhang"); 2. // age -> 20. name -> j3} public voidreflect1() {
        System.out.println("Java reflection mechanism - calling a class method 1.");
    }
    public void reflect2(int age, String name) {
        System.out.println("Java reflection mechanism - calling a class method 2.");
        System.out.println("age -> " + age + ". name -> "+ name); }}Copy the code

Manipulate attributes of a class through reflection

package net.xsoftlab.baike; import java.lang.reflect.Field; public class TestReflect { private String proprety = null; public static void main(String[] args) throws Exception { Class<? > clazz = Class.forName("net.xsoftlab.baike.TestReflect"); Object obj = clazz.newInstance(); Clazz.getdeclaredfield (clazz.getDeclaredField);"proprety");
        field.setAccessible(true);
        field.set(obj, "Java Reflection mechanism"); System.out.println(field.get(obj)); }}Copy the code

Dynamic proxy of reflection mechanism

// Get the classloader method TestReflecttestReflect = new TestReflect();
        System.out.println("Class loader" + testReflect.getClass().getClassLoader().getClass().getName()); package net.xsoftlab.baike; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; Interface Subject {public String say(String name, int age); Public String say(String name, int age) {RealSubject implements Subject {public String say(String name, int age) {return name + "" + age;
    }
}
class MyInvocationHandler implements InvocationHandler {
    private Object obj = null;
    public Object bind(Object obj) {
        this.obj = obj;
        return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), this);
    }
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object temp = method.invoke(this.obj, args);
        returntemp; }} /** * There are three types of classloaders in Java. * * 1) Bootstrap ClassLoader this loader is written in c++, which is rare in general development. * * 2) Extension ClassLoader is used to load Extension classes, usually corresponding to the jrelibext directory * * 3) AppClassLoader is used to load classes specified by classpath, which is the most common loader. It is also the default loader in Java. * * If you want to complete the dynamic proxy, you first need to define a subclass of the InvocationHandler interface to complete the proxy operation. * * @author xsoftlab.net * */ public class TestReflect { public static void main(String[] args) throws Exception { MyInvocationHandler demo = new MyInvocationHandler(); Subject sub = (Subject) demo.bind(new RealSubject()); String info = sub.say("Rollen", 20); System.out.println(info); }}Copy the code

4 Application example of reflection Stores an object of type String in an ArrayList whose generic type is Integer.

package net.xsoftlab.baike;
import java.lang.reflect.Method;
import java.util.ArrayList;
public class TestReflect {
    public static void main(String[] args) throws Exception {
        ArrayList<Integer> list = new ArrayList<Integer>();
        Method method = list.getClass().getMethod("add", Object.class);
        method.invoke(list, "Java reflection mechanism instance."); System.out.println(list.get(0)); }}Copy the code

Retrieves and modifies the array information by reflection

package net.xsoftlab.baike; import java.lang.reflect.Array; public class TestReflect { public static void main(String[] args) throws Exception { int[] temp = { 1, 2, 3, 4, 5 }; Class<? > demo = temp.getClass().getComponentType(); System.out.println("Array type:" + demo.getName());
        System.out.println("Array length" + Array.getLength(temp));
        System.out.println("First element of array:" + Array.get(temp, 0));
        Array.set(temp, 0, 100);
        System.out.println(The first element of the array is:+ Array.get(temp, 0)); }}Copy the code

Modify the size of an array through reflection

package net.xsoftlab.baike; import java.lang.reflect.Array; public class TestReflect { public static void main(String[] args) throws Exception { int[] temp = { 1, 2, 3, 4, 5, 6, 7, 8, 9}; int[] newTemp = (int[]) arrayInc(temp, 15);print(newTemp);
        String[] atr = { "a"."b"."c" };
        String[] str1 = (String[]) arrayInc(atr, 8);
        print(str1); Public static Object arrayInc(Object obj, int len) {Class<? > arr = obj.getClass().getComponentType(); Object newArr = Array.newInstance(arr, len); int co = Array.getLength(obj); System.arraycopy(obj, 0, newArr, 0, co);returnnewArr; } // Prints public static voidprint(Object obj) { Class<? > c = obj.getClass();if(! c.isArray()) {return;
        }
        System.out.println("Array length is:" + Array.getLength(obj));
        for (int i = 0; i < Array.getLength(obj); i++) {
            System.out.print(Array.get(obj, i) + ""); } System.out.println(); }}Copy the code

Apply reflection to the factory pattern

package net.xsoftlab.baike;
interface fruit {
    public abstract void eat();
}
class Apple implements fruit {
    public void eat() {
        System.out.println("Apple");
    }
}
class Orange implements fruit {
    public void eat() {
        System.out.println("Orange");
    }
}
class Factory {
    public static fruit getInstance(String ClassName) {
        fruit f = null;
        try {
            f = (fruit) Class.forName(ClassName).newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }
        returnf; }} /** * For normal factory mode when we add a subclass, we need to modify the factory class accordingly. When we add a lot of subclasses, it can get messy. Can refer to * http://baike.xsoftlab.net/view/java-factory-pattern * * * Java factory pattern now we use of reflection mechanism to realize the factory pattern, the factory class can be changed without add any number of subclasses. * * However, it is still a hassle to know the full package name and class name, which can be done using the Properties configuration file. * * read Java properties configuration file method can refer to * * * http://baike.xsoftlab.net/view/java-read-the-properties-configuration-file @author xsoftlab.net */ public class TestReflect { public static void main(String[] args) throws Exception { fruit f = Factory.getInstance("net.xsoftlab.baike.Apple");
        if(f ! = null) { f.eat(); }}}Copy the code

# # to summarize

I reprint the format may not be so good, the original format is still great. Almost all of the common uses of reflection have been included above, which meets the technical requirements of our final goal – a custom awesome database framework, and more information that you can collect on your own.

In the next article, we’re going to look at annotations, those familiar annotations.