Java 获取所有带有注释的类,并将它们添加到android中的hashMap中

Java 获取所有带有注释的类,并将它们添加到android中的hashMap中,java,android,hashmap,annotations,Java,Android,Hashmap,Annotations,我不确定这是否可行,但我基本上希望能够轻松地向列表中添加新项,只需添加带有特殊注释的类即可。我能想到的唯一一个例子就是我目前正在研究的东西。用户可以完成一系列“挑战”,目前我的应用程序中有一个“挑战”包,我希望能够在该包中创建一个新类,给它一个带有一些值的注释,如 @Challenge(key="new_challenge") public class NewChallenge extends Achievement {... } 该键对于每个质询都是不同的,它将是质询名称,然后在我的代码中,

我不确定这是否可行,但我基本上希望能够轻松地向列表中添加新项,只需添加带有特殊注释的类即可。我能想到的唯一一个例子就是我目前正在研究的东西。用户可以完成一系列“挑战”,目前我的应用程序中有一个“挑战”包,我希望能够在该包中创建一个新类,给它一个带有一些值的注释,如

@Challenge(key="new_challenge")
public class NewChallenge extends Achievement {... }
该键对于每个质询都是不同的,它将是质询名称,然后在我的代码中,我希望能够使用该“键”作为HashMap键将它们全部添加到HashMap中,因此它将是map.add(annotationkey,class);听起来这应该是可行的。我想知道,如果可能的话,这是否是一个正确的方式去做这件事,如何才能做到

编辑1 我能够用gradle实现反射,但它总是空的。找不到任何批注。我就是这样得到的

Challenge.java

package com.test.annotationtest.annotations;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@Retention(RetentionPolicy.RUNTIME)
public @interface Challenge {
  public String key();
}
package com.test.annotationtest.challenges

import com.test.annotationtest.R;
import com.test.annotationtest.annotation.Challenge;

@Challenge(key="test_challenge")
public class TestChallenge extends Achievement {
  public String name = "Test Challenge";
  public TestChallenge() {}
}
那么对于我的一个挑战,我有。。。 TestChallenge.java

package com.test.annotationtest.annotations;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@Retention(RetentionPolicy.RUNTIME)
public @interface Challenge {
  public String key();
}
package com.test.annotationtest.challenges

import com.test.annotationtest.R;
import com.test.annotationtest.annotation.Challenge;

@Challenge(key="test_challenge")
public class TestChallenge extends Achievement {
  public String name = "Test Challenge";
  public TestChallenge() {}
}
然后在我的主要活动中我有。。。 MainActivity.java

package com.test.annotationtest;
import...

public class MainActivity extends AppCompatActivity {
  public Reflections reflections = new Reflections("com.test"); // have tried "com.test.annotationtest" and "com.test.annotationtest.challenges"
  public static Map<String, Achievement> achievements;
  public static List<String> names = new ArrayList<>();

  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    achievements = getClasses();
    //setup recycler view and all that to show achievements
  }

  public Map<String, Achievement> getClasses() {
    Set<Class<?>> challengeClasses = reflections.getTypesAnnotatedWith(Challenge.class);
    Log.d("Main Activity", "The Challenges");
    Log.d("MAin Activity", "How many are there? " + Integer.toString(challengeClasses.size());
    //more processing on them;
  }
}
package com.test.annotationtest;
导入。。。
公共类MainActivity扩展了AppCompatActivity{
公共反射反射=新反射(“com.test”);//尝试过“com.test.annotationtest”和“com.test.annotationtest.challenges”
公共静态地图成果;
public static List name=new ArrayList();
@凌驾
创建时的公共void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
成就=获取类();
//设置“回收器”视图和所有显示成就的视图
}
公共映射getClasses(){

设置您可以创建自己的注释:

@Retention(RetentionPolicy.RUNTIME)
public @interface Challenge {
    public String key() default "";

}
然后您可以使用获取所有带注释的类

Set<Class<?>> challengeClasses = reflections.getTypesAnnotatedWith(Challenge.class);
但是请注意,应该谨慎使用反射,并且只有在真正必要时才使用反射。使用反射会使您失去对代码正确性的控制

示例:

com.test.webapp.Main

com.test.testapp.challenges.SomeChallenge

com.test.testapp.challenges.另一项挑战

pom.xml依赖关系(我使用的是Maven)


我没有更多的代码。目录与包相同。

创建注释类(使用
public@interface
)使用
RetentionPolicy.RUNTIME
。然后您可以按包级别获取所有类,并获取这些类上的注释,以阅读您的注释并执行有效的操作!!!!谢谢您,先生。要遍历集合
Map classesMap=challengelasses.stream().collect(Collectors.toMap(cl->cl.getAnnotation().key()),cl->cl.newInstance());
类似于Java 8方式。这应该是可行的。也许你必须处理一些异常,我不记得了。我不想麻烦你,但你能看看我所做的编辑,看看为什么在使用GetTypesAnotatedWith(Challenge.class)时它们没有显示出来吗方法。谢谢。我意识到我犯了一个错误。它应该是:
cl.getAnnotation(Challenge.class).key()
。但是说实话,这次我真的不知道如何帮助你。我刚刚做了一个类似的例子,也做了一些工作:
Reflections=newreflections(“com.test”);SET还可以处理更多的类。也许其他人会发现这个问题。
package com.test.testapp.annotations;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@Retention(RetentionPolicy.RUNTIME)
public @interface Challenge {
    public String key();
}
package com.test.testapp.challenges;

import com.test.testapp.annotations.Challenge;

@Challenge(key = "some_challenge")
public class SomeChallenge {
    public String name = "Some Challenge";

    @Override
    public String toString() {
        return "SomeChallenge{" +
                "name='" + name + '\'' +
                '}';
    }
}
package com.test.testapp.challenges;

import com.test.testapp.annotations.Challenge;

@Challenge(key = "another_challenge")
public class AnotherChallenge {
    public String name = "Another Challenge";

    @Override
    public String toString() {
        return "AnotherChallenge{" +
                "name='" + name + '\'' +
                '}';
    }
}
<dependency>
        <groupId>org.reflections</groupId>
        <artifactId>reflections</artifactId>
        <version>0.9.11</version>
</dependency>
some_challenge = SomeChallenge{name='Some Challenge'}
another_challenge = AnotherChallenge{name='Another Challenge'}