gpt4 book ai didi

java - 如何在java中的注释字段中设置值?

转载 作者:搜寻专家 更新时间:2023-11-01 04:05:39 26 4
gpt4 key购买 nike

我的注解类

@Target({java.lang.annotation.ElementType.FIELD})
@Retention(RetentionPolicy.CLASS)
public @interface Base {
int[] value();
}

实际类(class)

public class Demo {
@Base(1)
public int var;
public int var2;
public void call() {
InjectingClass.inject(this);
System.out.print(var + "");
}
}

如何将值 one 设置为 var 而不是在 var2 中?

最佳答案

有了 RUNTIME 生成,就很简单了

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@interface Set {
int value();
}

class Injector {
public static void inject(Object instance) {
Field[] fields = instance.getClass().getDeclaredFields();
for (Field field : fields) {
if (field.isAnnotationPresent(Set.class)) {
Set set = field.getAnnotation(Set.class);
field.setAccessible(true); // should work on private fields
try {
field.set(instance, set.value());
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}

class Demo {
@Set(1)
public int var;
public int var2;

public void call(){
Injector.inject(this);
System.out.println(var);
System.out.println(var2);
}
}
public class AnnotationDemo {
public static void main(String[] args) {
new Demo().call();
}
}

当你运行它时它会打印

1
0

它迭代声明的字段(即声明在此类中的所有字段,如果您希望它与从父类(super class)继承的字段一起使用,您也必须扫描这些字段)

检查注释的每个字段,如果找到则将字段设置为注释中存在的值。

当您想对 CLASS 或更简单的 SOURCE(类是 odd,我会使用源或运行时)注释执行相同操作时,您需要必须实现一个特殊的annotation processor Java 编译器在编译包含您感兴趣的注释的 .java 文件时调用的类。在下一步中,您将生成一个 .java 文本源文件,其中包含执行注入(inject)的代码。然后该代码也由编译器编译,您的 Injector 类在运行时将简单地调用生成的代码。

因此,您需要做的就是设法编写一个类 .java 文件,例如

class GeneratedInjector {
public static void inject(Object instance) {
if (instance instanceof Demo) {
injectDemo((Demo) instance);
}
}
public static void injectDemo(Demo demo) {
demo.var = 1;
}
}

在编译时基于注释分析。

所以在运行时,注释基本上不存在,运行的代码基本上如下

class GeneratedInjector {
public static void inject(Object instance) {
if (instance instanceof Demo) {
injectDemo((Demo) instance);
}
}
public static void injectDemo(Demo demo) {
demo.var = 1;
}
}

class Injector {
public static void inject(Object instance) {
GeneratedInjector.inject(instance);
}
}

class Demo {
public int var;
public int var2;

public void call(){
Injector.inject(this);
System.out.println(var);
System.out.println(var2);
}
}

public class AnnotationDemo {
public static void main(String[] args) {
new Demo().call();
}
}

由于这一切都是直接的普通旧 Java 而不是反射,因此您可以节省一些 CPU 周期。在大多数情况下,它很可能不会引人注意,但大量反射会产生影响。

https://deors.wordpress.com/2011/10/31/annotation-generators/有一些更好的信息

还有第三种混合方法,即在运行时生成字节码。这样,您将生成一个 .class 文件,其实现与 .java 文件大致相同。需要像 https://github.com/cglib/cglib 这样的字节码框架.这种方法也不容易与 Android 兼容,因为您需要为 Android 生成 .dex。但我想我什至在某个地方见过。

关于java - 如何在java中的注释字段中设置值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33971899/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com