检测给定对象内的当前注释传递给构造函数 [英] Detecting the present annotations within the given object passed into a constructor

查看:169
本文介绍了检测给定对象内的当前注释传递给构造函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的问题是:如何检测给定用户类/对象是否存在java注释(和在正确的位置)。



问题



假设我有两个java类:

  public class Line {
private List< Cell>细胞;

public Line(Object ... annotatedObjects){
//检查注释@Line和@Cell是否存在于annotatedObjects中。
}

//单元格的getter / setter。
}

public class Cell {
//一些成员
//一些方法
}

一个行对象包含Cells。



我也有两个注释,

  public @interface Line {
// some stuff here
}

public @interface单元格{
// some stuff here
}

包含我指定的@Line和@Cell注释的用户类(两个将为此示例),如:

  @ Line(name =pqr,schema =three)
public class AUserClass {
@Cell
private String aString;
}

@Line(name =xyz,schema =four)
public class AnotherUserClass {
@Cell(name =birthday)
private Date aDate;
}

问题:当我实例化一个新的Line对象时,以将用户类/对象传递到Line构造函数中。 Line构造函数然后找出传递的用户类/对象是否是可以处理的有效类。只有具有 @Line 注释的类和对其成员至少一个 @Cell 注释的用户类有效对象可以传递到Line对象的构造函数中。
所有其他传递的对象无效。传递有效的用户对象时,该对象中标记为 @Cell 的所有可用成员都将转换为单元格对象,并添加到单元格列表中。



我的问题:


  1. 可以检测此对象/类中的注释运行时,并且只为THIS传递的对象(我不想扫描类路径上的注释!)

  2. 可以检测 @Cell 已标记成员?这是需要的,因为Cell类不接受所有数据类型。

  3. 可以检索实际成员名称(在java文件中指定),以便用户不必指定成员单元名称。我想用户能够写 @Cell (没有名称)和 @Cell(name =aName),并且当仅指定 @Cell 时,将使用成员的名称。我不知道这个信息在运行时是否仍然可以使用反射。

  4. 如何检测注释是否在正确的地方?如果代码被标记为这样,那么对象应该忽略(或者可能抛出异常)?

      @Cell //哦哦,这是不好的:( 
    public class WrongClass {
    // some members
    } / pre>

  5. 你能提供一些启动代码,所以我知道一点点去解决这个问题。反射。BTW:我使用最新的jvm 1.6 +

感谢您的帮助!

解决方案

首先,您需要在注释中加入保留政策,以便您可以使用反思阅读。

  @Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public static @interface Line {

}

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public static @interface Cell {

}

其次,您需要测试类是否具有 isAnnotationPresent(annotationClass)的Line注释。此方法可从 java.lang.Class 和java.lang.reflect.Field访问。



注意:您需要检索 class.getDeclaredField(fieldName)的私有字段。



3。我不认为你可以使注释具有基于propertyName的默认值,但你可以使名称可选,通过提供一个默认 String name()default DEFAULT ,并在遍历字段时检查该值,并使用存储在 name() propertyName


My question in short: how do I detect if a java annotation is present (and in the right place) for a given user class/object.

Details of the "problem"

Lets say I have two java classes:

public class Line {
   private List<Cell> cells;

   public Line(Object... annotatedObjects) {
     // check if annotations @Line and @Cell are present in annotatedObjects.
   }

   // getter/setter for cells.
}

public class Cell {
   // some members
   // some methods
}

A Line object holds Cells.

I also have two annotations, like:

public @interface Line {
  // some stuff here
}

public @interface Cell {
  // some stuff here
}

I also have a bunch of user classes (two will do for this example) that contain the @Line and @Cell annotations I specified, like:

@Line(name="pqr", schema="three")
public class AUserClass {
   @Cell
   private String aString;
}

@Line(name="xyz", schema="four")
public class AnotherUserClass {
   @Cell(name="birthday")
   private Date aDate;
}

The problem: When I instantiate a new Line object, I want to be able to pass the user classes/objects into the Line constructor. The Line constructor then finds out if the passed user classes/objects are valid classes that can be processed. Only user classes that have a @Line annotation for the class, and at least one @Cell annotation for its members are valid objects that can be passed into the constructor of the Line object. All other passed objects are invalid. The moment a valid user object is passed, all the available members that are tagged as @Cell in that object are transformed to Cell objects and added to the cells list.

My questions:

  1. is this possible to detect the annotations in this object/class at runtime, and only for THIS passed object (I don't want to scan for annotations on the classpath!)?
  2. is it possible to detect the datatype of the @Cell tagged members? This is needed because the Cell class doesn't accept all datatypes.
  3. is it possible to retrieve the actual member name (specified in the java file) so that the user doesn't have to specify the members Cell name. I want the user to be able to write @Cell (without a name) and @Cell(name="aName"), and when only @Cell is specified, the name of the member is used instead. I have no idea if this information is still available at runtime using reflection.
  4. How to detect if the annotations are in the right place?If code is tagged like this, then the object should be ignored (or maybe an exception is thrown)?

    @Cell // oh oh, that's no good :(
    public class WrongClass {
    // some members
    }

  5. Could you provide some startup code, so I know a little to get going with this problem. I am really new to annotations and reflection. BTW: I am using the latest jvm 1.6+

Thank you for your kind help!

解决方案

First you need to have retention policy on your annotations so you can read them with reflection

  @Retention(RetentionPolicy.RUNTIME)
  @Target(ElementType.TYPE)
  public static @interface Line {

  }

  @Retention(RetentionPolicy.RUNTIME)
  @Target(ElementType.FIELD)
  public static @interface Cell {

  }

Second you need to test if the class has the Line annotation with isAnnotationPresent(annotationClass). This method is accessible from java.lang.Class and a java.lang.reflect.Field.

NOTE: that you need to retrieve the fields that are private with class.getDeclaredField(fieldName).

3. I don't think you can make an annotation have a default value based on a propertyName but you can make name optional by providing a default String name() default DEFAULT and check for that value when iterating through the fields and either use the value stored in name() or the propertyName

这篇关于检测给定对象内的当前注释传递给构造函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆