检测传递给构造函数的给定对象中的当前注释
简而言之,我的问题是:如何检测给定用户类/对象是否存在 java 注释(并且位于正确的位置)。
“问题”的详细信息
假设我有两个 java 类:
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
}
Line 对象保存 Cells。
我还有两个注释,例如:
public @interface Line {
// some stuff here
}
public @interface Cell {
// 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
的所有可用成员都会转换为 Cell 对象并添加到单元列表中。
我的问题:
- 是否可以在运行时检测此对象/类中的注释,并且仅针对此传递的对象(我不想扫描类路径上的注释!)?
- 是否可以检测
@Cell
标记成员的数据类型?这是必需的,因为 Cell 类不接受所有数据类型。 - 是否可以检索实际的成员名称(在 java 文件中指定),以便用户不必指定成员单元名称。我希望用户能够编写
@Cell
(没有名称)和@Cell(name="aName")
,并且仅当@Cell<指定 /code> 时,将使用成员的名称。我不知道这些信息在运行时是否仍然可以使用反射获得。
- 如何检测注释是否在正确的位置?如果代码是这样标记的,那么该对象应该被忽略(或者可能抛出异常)?
@Cell // 哦哦,这不好:( 公共类错误类{ // 一些成员 }
- 您能否提供一些启动代码,以便我了解一些如何解决这个问题。我对注释和反射真的很陌生。顺便说一句:我正在使用最新的 jvm 1.6+
感谢您的帮助!
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:
- 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!)?
- is it possible to detect the datatype of the
@Cell
tagged members? This is needed because the Cell class doesn't accept all datatypes. - 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. - 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 }
- 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!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
首先,您需要对注释制定保留策略,以便可以通过反射读取它们。
其次,您需要使用
isAnnotationPresent(annotationClass)
测试该类是否具有 Line 注释。此方法可从 java.lang.Class 和 java.lang.reflect.Field 访问。注意:您需要使用
class.getDeclaredField(fieldName)
检索私有字段。3.
我认为您不能使注释具有基于 propertyName 的默认值,但您可以通过提供默认String name() default DEFAULT
使名称可选并在遍历字段时检查该值,并使用存储在name()
或propertyName
中的值First you need to have retention policy on your annotations so you can read them with reflection
Second you need to test if the class has the Line annotation with
isAnnotationPresent(annotationClass)
. This method is accessible fromjava.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 defaultString name() default DEFAULT
and check for that value when iterating through the fields and either use the value stored inname()
or thepropertyName
是的,使用 isAnnotationPresent
注意该注释的范围保留在
运行时
仅可用,
Yes it is very well possible using isAnnotationPresent
Note that annotation which are scoped to retain at
Runtime
will be available only,