Skip to content

hhy50/reflect-linker

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

reflect-linker

reflect-linker 是一个用于链接反射对象的库,它可以帮助你在运行时代替反射去使用对象中字段和方法。

简单尝试:

  1. 引入依赖
<dependency>
    <groupId>io.github.hhy</groupId>
    <artifactId>reflect-linker</artifactId>
    <version>1.0.0</version>
</dependency>
  1. 定义访问规则 以ArrayList举例
@Target.Bind("java.util.ArrayList")
public interface MyArrayList {
    
    void add(Object o);
    
    @Field.Getter("elementData")
    Object[] getElementData();
    
    @Field.Setter("elementData")
    void setElementData(Object[] elementData);
}
  1. 创建连接器
class Example {
    public static void main(String[] args) throws LinkerException {
        MyArrayList list = LinkerFactory.createLinker(MyArrayList.class, new ArrayList<>());
        
        // do thing
    }
}

更多用法:

  1. 链式表达式访问
class User {
    private String name;
    private int age;
}
class UserWrap {
    private User user;
}
@Target.Bind("io.github.hhy50.linker.example.nest.UserWrap")
interface UserVisitor {
    @Field.Getter("user")
    User getUser();

    @Field.Setter("user")
    void setUser(User user);

    @Field.Setter("user.name")
    void setName(String val);

    @Field.Getter("user.name")
    String getName();

    @Field.Setter("user.age")
    void setAge(int val);

    @Field.Getter("user.age")
    int getAge();
}

class Example {
    public static void main(String[] args) throws LinkerException {
        UserWrap userWrap = new UserWrap();
        UserVisitor userVisitor = LinkerFactory.createLinker(UserVisitor.class, userWrap);
        userVisitor.setUser(new User());
        userVisitor.setAge(20);
        userVisitor.setName("example");

        // do something
    }
}
  1. 动态类型
class A { }
class B {
    String val = "this is b'val";
}
class A2 extends A {
    private B b;
    public A2(B b) {
        this.b = b;
    }
}
class MyObject {
    private A a;
}
@Target.Bind("io.github.hhy50.linker.example.dynamic.MyObject")
interface MyObjectVisitor {
    @Field.Setter("a")
    void setA(A val);

    @Field.Getter("a.b")
    B getB();
}
class Example {
    public static void main(String[] args) throws LinkerException {
        MyObject myObj = new MyObject();
        MyObjectVisitor myObjVisitor = LinkerFactory.createLinker(MyObjectVisitor.class, myObj);
        myObjVisitor.setA(new A2(new B()));
        System.out.println(myObjVisitor.getB().val);

        // do something
    }
}

上面表达式@Field.Getter("a.b")中, A class是没有B field的, B field存在于A的子类中, 这样的字段视为运行时字段, 这样会在调用对应方法时动态获取A的类型

如果您非常在意执行性能, 可以使用@Typed指定A class的类型, 将B field变为已知的字段

//@Typed(name = "a", type = "io.github.hhy50.linker.example.dynamic.A2") // 也可以声明在这里
@Target.Bind("io.github.hhy50.linker.example.dynamic.MyObject")
interface MyObjectVisitor {
    @Field.Setter("a")
    void setA(A val);

    @Typed(name = "a", type = "io.github.hhy50.linker.example.dynamic.A2")
    @Field.Getter("a.b")
    B getB();
}

然后重新run

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages