Java:允许带有自定义注释的对象的集合

发布于 2024-09-27 19:27:49 字数 421 浏览 2 评论 0原文

我想用 @MyEntity 注释来注释一些类

public @interface MyEntity {}

@MyEntity
public class MyClass { ... }

,并定义一个集合,其中只允许具有该注释的类(无需将它们定义为 public class MyClass Implements XXX):

List<MyEntity> list = new ArrayList<MyEntity>();
list.add(new MyClass())

上面的代码导致编译错误“ArrayList 类型中的方法 add(MyEntity) 不适用于参数 (MyClass)”。有没有办法定义一个集合,只允许具有给定注释的对象?

I'd like to annotate some classes with a @MyEntity annotation

public @interface MyEntity {}

@MyEntity
public class MyClass { ... }

And define a collection where only classes with that annotation are allowed (with no need to define them as public class MyClass implements XXX):

List<MyEntity> list = new ArrayList<MyEntity>();
list.add(new MyClass())

The above code results in a complation error "The method add(MyEntity) in the type ArrayList is not applicable for the arguments (MyClass)". Is there a way to define a collection that only allows objects with a given annotation?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

山人契 2024-10-04 19:27:49

简短的回答是否定的。

您的问题是 List 定义了 MyEntity 或其子类的列表(即,如果我们有 @interface AnotherEntity extends MyEntity 那么我们可以放置 AnotherEntity 到此列表)。

MyClass 不扩展/实现 MyEntity,它是用它注释的。

即使有可能,效率也不会很高。您不知道哪些方法或字段可用,MyEntity 不描述对象的接口。因此,它唯一的用途就是过滤错误的插入。您可以轻松地实现它,提供您的 List 实现:

List<?> myEntities = new LinkedList<?> {
   @Override 
   public boolean add(Object obj) {
       if (obj != null && obj.getClass().isAnnotationPresent(MyEntity.class)) {
           return super.add(obj);
       }
       throw new IllegalArgumentException("Only objects annotated with MyEntity are allowed");
   }

   @Override
   public boolean addAll(Collection<?> objs) {
      //something similar, maybe with Collections2.filter from Google Collections
   }
};

The short answer is no.

Your problem is that List<MyEntity> defines a list of MyEntity's or its subclasses (i.e. if we have @interface AnotherEntity extends MyEntity then we could put AnotherEntity to this list).

Class MyClass doesn't extend/implement MyEntity, it's annotated with it.

Even if it was possible, it wouldn't be efficient. You wouldn't know which methods or fields are available, MyEntity doesn't describe your object's interface. So, the only thing it could be used for is filtering wrong insertions. You can implement it easily providing your List implementation:

List<?> myEntities = new LinkedList<?> {
   @Override 
   public boolean add(Object obj) {
       if (obj != null && obj.getClass().isAnnotationPresent(MyEntity.class)) {
           return super.add(obj);
       }
       throw new IllegalArgumentException("Only objects annotated with MyEntity are allowed");
   }

   @Override
   public boolean addAll(Collection<?> objs) {
      //something similar, maybe with Collections2.filter from Google Collections
   }
};
寂寞清仓 2024-10-04 19:27:49

不要认为这是可能的。为什么不让他们实现一个无方法接口呢?

Don't think this is possible. Why not have them implement a no-method interface instead?

故人如初 2024-10-04 19:27:49

注解的存在不会修改带注解的类的类型。

您可以创建一个仅包含用您的注释注释的元素的集合。您需要为集合创建一个包装类,该类使用反射来检查插入时注释是否存在。

它仍然无法让您进行编译时类型检查。为此,您需要一些直接影响可插入项目类型(接口或超类等)的东西

The presence of an annotation doesn't modify the annotated class's type.

You could create a collection that only contains elements which are annotated with your annotation. You would need to make a wrapper class for the collection that uses reflection to check for the presence of the annotation on insertion.

It still won't get you compile-time type checking. For that you would need something which directly affects the insertable items' type (interface or superclass, etc.)

陌上青苔 2024-10-04 19:27:49

只需重写 list: add、addAll 和构造函数的方法即可过滤具有预期注释的类。

Just override methods of list: add, addAll and constructors, to filter classes that have expected annotation.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文