1. 应用场景
当你有一个只能用Object来表示的对象
// in User.java
class User {
String name = " user'name ";
String getName() {
return name;
}
}
// in Main.java
Object user = Class.forName("io.github.hhy.test.User").newInstance();
你需要访问user这个对象的字段或者方法时, 大多人都会使用反射去操作, 这个时候你可以考虑使用 reflect-linker
引入依赖
<dependency>
<groupId>io.github.hhy50</groupId>
<artifactId>reflect-linker</artifactId>
<version>1.0.6</version>
</dependency>
// in UserVisitor.java
// 需要提前定义访问规则
@Target.Bind("io.github.hhy.test.User")
public interface UserVisitor {
// 指定字段 getter
@Field.Getter("name")
String getName();
// 指定字段 setter
@Field.Setter("name")
void setName(String name);
// 指定方法
@Method.Name("getName")
String getNameMethod();
}
// in Main.java
Object user = Class.forName("io.github.hhy.test.User").newInstance();
UserVisitor linker = LinkerFactory.createLinker(UserVisitor.class, user);
System.out.println(linker.getName());
2. 优势
强大的链式访问能力
@Target.Bind("io.github.hhy.test.User")
public interface UserVisitor {
// 链式访问String的value字段
@Field.Getter("name.value")
char[] getNameCharArray();
// 调用String的父类方法。也就是Object里面的toString()
@Method.InvokeSuper
@Method.Name("name.toString")
String nameSuperToString();
// 链式调用String.length()方法
@Method.Name("name.length")
int nameLen();
}
可以支持多级的链式访问/调用
优雅的类型转换
reflect-linker支持方法返回一个链接器, 也支持在参数里面使用链接器
@Target.Bind("io.github.hhy.test.User")
public interface UserVisitor {
@Field.Getter("name")
MyString getName();
@Field.Setter("name")
void setName(MyString name);
}
// 链接到 String
@Target.Bind("java.lang.String")
interface MyString {
}
运行时类型
运行时类型是指 @Target.Bind指定的类为实际类的父类
手动将User类的字段和方法移动到他的子类中, 上面的链接器依然有效
class User {}
class UserVo extends User {
String name = " user'name ";
String getName() {
return name;
}
}
// UserVisitor
@Target.Bind("io.github.hhy.test.User")
public interface UserVisitor {
//....
}
// Main.java
// 这里也需要改成
Object user = Class.forName("io.github.hhy.test.UserVo").newInstance();
3. 总结
reflect-linker很轻量化, 仅依赖了asm来动态生成接口类的实现类