这是我的代码:
@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") 的值?
是的,如果您的 Column 注释具有运行时保留
@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());
}
更新:要获取私有字段,请使用
Myclass.class.getDeclaredFields()
当然是。这是一个示例注释:
@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());
}
}
对于像你这样的字段注释没有太大的不同。
干杯!
我从来没有做过,但看起来 Reflection 提供了这个。 Field
是一个 AnnotatedElement
,所以它有 getAnnotation
。 This page 有一个示例(复制如下);如果您知道注释的类并且注释策略在运行时保留注释,则非常简单。自然,如果保留策略在运行时不保留注解,您将无法在运行时查询它。
一个已被删除的答案 (?) 提供了一个指向 an annotations tutorial 的有用链接,您可能会觉得它有帮助;我在这里复制了链接,以便人们可以使用它。
this page 中的示例:
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);
}
}
详细说明@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());
虽然到目前为止给出的所有答案都是完全有效的,但还应牢记 google reflections library 以获得更通用和更简单的注释扫描方法,例如
Reflections reflections = new Reflections("my.project.prefix");
Set<Field> ids = reflections.getFieldsAnnotatedWith(javax.persistence.Id.class);
通常情况下,您对字段具有私有访问权限,因此您不能在反射中使用 getFields。而不是这个,你应该使用 getDeclaredFields
因此,首先,您应该知道您的 Column 注释是否具有运行时保留:
@Retention(RetentionPolicy.RUNTIME)
@interface Column {
}
之后,您可以执行以下操作:
for (Field f: MyClass.class.getDeclaredFields()) {
Column column = f.getAnnotation(Column.class);
// ...
}
显然,您想对字段做一些事情 - 使用注释值设置新值:
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()
)
);
}
在我的情况下,您还可以使用泛型类型,在您可以执行以下操作之前考虑到所有内容:
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(...)();
但能做到这一点...
对于少数要求通用方法的人,这应该对您有所帮助(5年后:p)。
对于下面的示例,我从具有 RequestMapping 注释的方法中提取 RequestMapping URL 值。要使其适用于字段,只需更改
for (Method method: clazz.getMethods())
至
for (Field field: clazz.getFields())
并将 RequestMapping 的使用替换为您要阅读的任何注释。但请确保注解具有@Retention(RetentionPolicy.RUNTIME)。
public static String getRequestMappingUrl(final Class<?> clazz, final String methodName)
{
// Only continue if the method name is not empty.
if ((methodName != null) && (methodName.trim().length() > 0))
{
RequestMapping tmpRequestMapping;
String[] tmpValues;
// Loop over all methods in the class.
for (Method method: clazz.getMethods())
{
// If the current method name matches the expected method name, then keep going.
if (methodName.equalsIgnoreCase(method.getName()))
{
// Try to extract the RequestMapping annotation from the current method.
tmpRequestMapping = method.getAnnotation(RequestMapping.class);
// Only continue if the current method has the RequestMapping annotation.
if (tmpRequestMapping != null)
{
// Extract the values from the RequestMapping annotation.
tmpValues = tmpRequestMapping.value();
// Only continue if there are values.
if ((tmpValues != null) && (tmpValues.length > 0))
{
// Return the 1st value.
return tmpValues[0];
}
}
}
}
}
// Since no value was returned, log it and return an empty string.
logger.error("Failed to find RequestMapping annotation value for method: " + methodName);
return "";
}
我使用它的一种方式:
protected List<Field> getFieldsWithJsonView(Class sourceClass, Class jsonViewName){
List<Field> fields = new ArrayList<>();
for (Field field : sourceClass.getDeclaredFields()) {
JsonView jsonViewAnnotation = field.getDeclaredAnnotation(JsonView.class);
if(jsonViewAnnotation!=null){
boolean jsonViewPresent = false;
Class[] viewNames = jsonViewAnnotation.value();
if(jsonViewName!=null && Arrays.asList(viewNames).contains(jsonViewName) ){
fields.add(field);
}
}
}
return fields;
}
要在 java 中读取注释的值,请尝试按照以下步骤操作:
创建注释。遵循下面目标类中的逻辑。访问输出中的值。
注解
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.TYPE}) // make annotation usable only for classes
@Retention(RetentionPolicy.RUNTIME) // make annotation available at the runTime
public @interface EntryPoint {
String url();
}
目标
// just remember to import your annotation in this case "EntryPoint"
import java.lang.annotation.Annotation;
@EntryPoint(url = "api/v1/demo")
public class Demo {
// get class of this.
private final Class<? extends Demo> demo = this.getClass();
// get specific annotation (EntryPoint.class)
private final Annotation annotation = demo.getAnnotation(EntryPoint.class);
// instantiate annotation and assign it value from the class annotation.
final EntryPoint entryPoint = (EntryPoint) annotation;
}
输出
public class Main {
public static void main(String[] args) {
// create an object of the class with the annotation.
Demo demo = new Demo();
System.out.println(demo.entryPoint.url());
}
}
结果是“api/v1/demo”
不定期副业成功案例分享
Myclass.class.getDeclaredFields()
获取私有字段