随着RUNTIME
代,即当你运行它打印
1
0
它遍历声明的字段(即所有领域,其中声明是在这个类,如果是很简单
@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();
}
}
你想要这个工作与超类的继承字段,你也必须扫描这些)
检查ann的每个字段如果找到,则将该字段设置为注释中存在的值。
当你想要做同样的一个CLASS
或简单SOURCE
(类odd,我会用源或运行时)注释你就必须实行特殊annotation processor类由Java编译器时调用编译包含您感兴趣的注释的.java文件。在下一步中,您将生成一个.java文本源文件,其中包含执行注入的代码。该代码然后也由编译器编译,并且您在运行时的类将简单地调用生成的代码。
因此,所有你需要做的是在管理基于注释的分析编译的时候写一个类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/有一些更漂亮的信息
还有第三种混合方法,这是在运行时生成字节码。这样你就可以生成一个与.java文件大致相同的.class文件。需要像https://github.com/cglib/cglib这样的字节码框架。由于您需要为Android生成.dex,因此该方法也不易与Android兼容。但我想我甚至在某个地方见过。
咦?那不是你已经做过的吗?目前的代码有什么问题? – Tunaki
对不起,我没有实现InjectingClass。如何实现InjectingClass? –
使用'RetentionPolicy.CLASS'?非常困难(但请参阅http://google.github.io/dagger/),因为这意味着您需要一个注释处理器,它在编译时生成代码,然后“InjectingClass”几乎不做任何事情。用'.RUNTIME'代码(反射)的几行。 – zapl