Comparison between reflection toolkit JOOR, Hutool and native reflection

Posted by shafiq2626 on Fri, 31 Dec 2021 21:01:35 +0100

Comparison of three codes

Before analyzing and comparing the three, we first intuitively look at the differences between the three through the amount of code.

Let's first look at an example of reflection.

Native reflection implementation

JOOR implementation

Hutool implementation

First of all, subjectively, JOOR and Hutool are much streamlined at the api level, and encapsulate exceptions without forced capture. JOOR supports chain programming on the basis of Hutool.

JOOR main API

Let's take a look at the main API of JOOR

public class JoorExample {
    public static void main(String[] args) {
        String name = null;
        Kale kale;
        // [create class]
        kale = Reflect.onClass(Kale.class).create().get(); // No parameters
//        kale = Reflect.on(Kale.class).create("kale class name").get();//  With parameters
        System.out.println("------------------> class name = " + kale.getClass());
 
        // [calling method]
        Reflect.on(kale).call("setName","call setName");// Multi parameter
        System.out.println("Call method: name = " + Reflect.on(kale).call("getName"));// No parameters
 
        // [get variable]
        name = Reflect.on(kale).field("name").get();// complex
        name = Reflect.on(kale).get("name");// simple
        System.out.println("Get variable value: name = " + name);
 
        // [set value of variable]
        Reflect.on(kale).set("className", "hello");
        System.out.println("Set the value of the variable: name = " + kale.getClass());
        System.out.println("Set the value of the variable: name = " + Reflect.on(kale).set("className", "hello2").get("className"));
 
    }
}

It can be seen that JOOR has built-in set and get methods for us to call, which can directly obtain the values of some attributes, and chain programming also greatly simplifies the development.

Does JOOR support several java Native ways (full class name, object instance, class object of class) to obtain reflective objects?

From the above example, we know that JOOR supports obtaining reflective objects based on object instances.

Let's look at the following example

String world = onClass("java.lang.String")  // After on, put the full name of the class. Here is the String class
        .create("Hello World") // Pass the string "Hello World" into the constructor
        .call("substring", 6)  // Execute the subString method and pass in 6 as a parameter
        .call("toString")      // Execute toString method
        .get();                // Get the wrapped class. Here is a String object
 
String substring = onClass("java.lang.String")
        .create("Hello World")
        .as(StringProxy.class) // Create a proxy for the wrapper class
        .substring(6);         // Access proxy method
 
String string = onClass(String.class)
        .create("Hello World")
        .as(StringProxy.class) // Create a proxy for the wrapper class
        .substring(6);         // Access proxy method
 
 
 
System.out.println(world);
System.out.println(substring);
System.out.println(string);

We can see that the reflection object can be obtained through the full class name and the class object of the class. At the same time, it also supports the proxy method of accessing the jdk.

JOOR implementation proxy

Let's first write a static proxy, including proxy class and ordinary class. Waiter is the proxy class of ZhangSan.

public interface Restaurant {
    void eat();
}
public class ZhangSan implements Restaurant{
    @Override
    public void eat() {
        System.out.println("Eat eat eat");
    }
}
public class Waiter implements Restaurant{
    private ZhangSan zhangSan;
 
    public Waiter(ZhangSan zhangSan) {
        this.zhangSan = zhangSan;
    }
 
    @Override
    public void eat() {
        System.out.println("cook");
        zhangSan.eat();
        System.out.println("Wash the dishes");
    }
}

Implement agent testing

Here, the proxy object must be passed into the object in the form of construction method to enhance it, and the enhanced method can be realized through the proxy.

conclusion

It can be seen from the above cases that due to the characteristics of chain programming, JOOR has better code simplification and scalability than the other two, and it includes some advanced applications, such as agents. Although the code is not as concise as the original, it is easy to understand.

If you need to use, you can use the reflection encapsulation class in JOOR or Hutool by introducing the following packages.

//JOOR
<dependency>
    <groupId>org.jooq</groupId>
    <artifactId>joor-java-8</artifactId>
    <version>0.9.13</version>
</dependency>
 
//Hutool
<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>5.4.6</version>
</dependency>

How to use it can be flexibly selected according to the actual situation.