碰到一个任务, 需要根据注解来创建一个新对象,而不能使用new关键字. 在取得注解的内容后,不知道如何根据注解内容来生成一个新的User对象?
[code="java"]package annopractise;
import java.lang.reflect.Field;
public class UserAnnoTest {
@UserAnno(id = 13, name = "sanan")
public User user;
public UserAnnoTest() throws ClassNotFoundException {
Class<?> cl = UserAnnoTest.class;
for (Field field : cl.getFields()) {
UserAnno userAnno = field.getAnnotation(UserAnno.class);
if (userAnno != null) {
[color=red]// 此处该如何继续, 这里已经得到注解内容, 但是不知道如何创建User对象[/color]
}
}
}
@Override
public String toString() {
return user.toString();
}
public static void main(String[] args) throws ClassNotFoundException {
UserAnnoTest annoTest = new UserAnnoTest();
System.out.println(annoTest);
}
}[/code]
User和UserAnno的代码如下:
[code="java"]package annopractise;
public class User {
int id;
String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "id: " + id + "\tname: " + name + "\n";
}
}[/code]
[code="java"]package annopractise;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface UserAnno {
int id();
String name() default "";
}[/code]
还可以这样做
Class userClass = User.class;
Constructor constructor = userClass.getConstructor();
user = constructor.newInstance();
user.setId(id);
user.setName(name);
但是记住,如果User中有多个构造方法,一定记得申明一个无参的构造方法,如果一个构造方法都没有的话就不用担心。
还有获取类属性应该用这个方法 Field[] fields = clazz.getDeclaredFields();
我使用你提供的getFields方法无任何返回值,具体原因还在查。
package com.annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
/**
Time: 3:27 PM
*/
public class Main {
@UserAnno(id = 1, name = "ZhongGang")
private User user;
public Main() {
Class clazz = Main.class;
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
UserAnno annotation = field.getAnnotation(UserAnno.class);
if (annotation != null) {
int id = annotation.id();
String name = annotation.name();
try {
Class userClass = User.class;
Constructor constructor = userClass.getConstructor(Integer.class, String.class);
user = constructor.newInstance(id, name);
} catch (InstantiationException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
} catch (IllegalAccessException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
} catch (NoSuchMethodException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
} catch (InvocationTargetException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
}
}
}
public static void main(String[] args) {
Main main = new Main();
System.out.println(main.toString());
}
public String toString() {
return user.toString();
}
}
User中记得添加User的构造方法
public User(Integer id, String name) {
this.id = id;
this.name = name;
}
getFields()只能访问类中声明为公有的字段,私有的字段它无法访问.getDeclaredFields()能访问类中所有的字段,与public,private,protect无关
sorry,看错,原来你的user是public的。是我搞错了,我申明成private的了。
显然 通常这个User通常是不会引入到类中的,而其注解是需要的,因为它是解析的元数据,算是入口,所以可以这样写,来实现注解的功能,即把构造延迟到应用程序的解析上
[code="java"]
public static void main(String[] args) throws Exception {
Class<?> cl = UserAnnoTest.class;
for (Field field : cl.getFields()) {
UserAnno ano = field.getAnnotation(UserAnno.class);
if (ano != null) {
Class<?> filedType = field.getType();
Object f = filedType.newInstance();
Method m = f.getClass().getMethod("setName", String.class); // 可以根据UserAnno字段來动态获取
m.invoke(f, ano.name());
Method m2 = f.getClass().getMethod("setId", int.class); // 可以根据UserAnno字段來动态获取
m2.invoke(f, ano.id());
System.out.println(f);
}
}
}
[/code]