是否有可能读取在Java注释的价值?
这是我的代码:
@Column(columnName="firstname") private String firstName; @Column(columnName="lastname") private String lastName; public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; }
是否有可能在另一个类中读取我的注释@Column( columnName =“xyz123”)的值?
是的,如果您的列注释具有运行时保留
@Retention(RetentionPolicy.RUNTIME) @interface Column { .... }
你可以做这样的事情
for (Field f: MyClass.class.getFields()) { Column column = f.getAnnotation(Column.class); if (column != null) System.out.println(column.columnName()); }
当然如此。 这是一个示例注释:
@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface TestAnnotation { String testText(); }
和一个示例注释的方法:
class TestClass { @TestAnnotation(testText="zyx") public void doSomething(){} }
另一个类中的示例方法打印testText的值:
Method[] methods = TestClass.class.getMethods(); for (Method m : methods) { if (m.isAnnotationPresent(TestAnnotation.class)) { TestAnnotation ta = m.getAnnotation(TestAnnotation.class); System.out.println(ta.testText()); } }
与您的字段标注差异不大。
Cheerz!
我从来没有做过,但它看起来像reflection提供这一点。 Field
是一个AnnotatedElement
,所以它有getAnnotation
。 这个页面有一个例子(复制下面); 如果您知道注释的类并且注释策略是否在运行时保留了注释,那么就非常简单。 当然,如果保留策略在运行时不保留注释,则在运行时将无法查询。
自从被删除的答案(?)为注释教程提供了有用的链接,您可能会发现它有帮助; 我在这里复制链接,以便人们可以使用它。
来自此页面的示例:
import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.reflect.Method; @Retention(RetentionPolicy.RUNTIME) @interface MyAnno { String str(); int val(); } class Meta { @MyAnno(str = "Two Parameters", val = 19) public static void myMeth(String str, int i) { Meta ob = new Meta(); try { Class c = ob.getClass(); Method m = c.getMethod("myMeth", String.class, int.class); MyAnno anno = m.getAnnotation(MyAnno.class); System.out.println(anno.str() + " " + anno.val()); } catch (NoSuchMethodException exc) { System.out.println("Method Not Found."); } } public static void main(String args[]) { myMeth("test", 10); } }
虽然到目前为止给出的所有答案都是完全有效的,但还应该记住googlereflection库,以获得更通用和更容易的注释扫描方法,例如
Reflections reflections = new Reflections("my.project.prefix"); Set<Field> ids = reflections.getFieldsAnnotatedWith(javax.persistence.Id.class);
详细阐述@Cephalopod的答案,如果你想列表中的所有列名,你可以使用这个oneliner:
List<String> columns = Arrays.asList(MyClass.class.getFields()) .stream() .filter(f -> f.getAnnotation(Column.class)!=null) .map(f -> f.getAnnotation(Column.class).columnName()) .collect(Collectors.toList());
你也可以使用genericstypes,就我而言,考虑到所有的东西之前你可以做一些事情:
public class SomeTypeManager<T> { public SomeTypeManager(T someGeneric) { //That's how you can achieve all previously said, with generic types. Annotation[] an = someGeneric.getClass().getAnnotations(); } }
请记住,这不会等于100%SomeClass.class.get(…)();
但可以做的伎俩…
在一般情况下,您可以私人访问字段,所以您不能在reflection中使用getFields 。 而不是这个,你应该使用getDeclaredFields
因此,首先,您应该了解Column注释是否具有运行时保留:
@Retention(RetentionPolicy.RUNTIME) @interface Column { }
之后,你可以做这样的事情:
for (Field f: MyClass.class.getDeclaredFields()) { Column column = f.getAnnotation(Column.class); // ... }
显然,你想用field来做一些事情 – 使用注释值设置新值:
Column annotation = f.getAnnotation(Column.class); if (annotation != null) { new PropertyDescriptor(f.getName(), Column.class).getWriteMethod().invoke( object, myCoolProcessing( annotation.value() ) ); }
所以,完整的代码可以看起来像这样:
for (Field f : MyClass.class.getDeclaredFields()) { Column annotation = f.getAnnotation(Column.class); if (annotation != null) new PropertyDescriptor(f.getName(), Column.class).getWriteMethod().invoke( object, myCoolProcessing( annotation.value() ) ); }