有没有办法检查Generic类是否存在字段?
public class Person {
public String name;
public String street;
...
}
public class Car {
public String name;
...
}
public abstract class Base<E> {
...
public void doSomething(E entity) {
String street = "";
//Check if the generic entity has a "street" or not.
// If a Person arrives: then the real street should appear
// If a Car arrives: then an empty string would be needed
logger.trace("Entity name: {}", street);
}
}
答案 0 :(得分:4)
除了使用反射,我没有别的办法。应该是这样的(未经测试):
try {
Field field = entity.getClass().getField("street");
if (field.getType().equals(String.class) {
street = (String) field.get(entity);
}
} catch (NoSuchFieldException ex) {
/* ignore */
}
如果您可以控制类型层次结构,则可以使用HasStreet
方法创建getStreet()
之类的界面,并让您的实体与街道实现它。这样会更清晰:只需检查该接口是否已实现,然后转换并调用该方法。
答案 1 :(得分:0)
如果您可以减少E的不同选项,那么您只需使用instanceof
检查班级:
public abstract class AbstractEntity {
public string name;
}
public class Person extends AbstractEntity {
public String street;
...
}
public class Car extends AbstractEntity {
...
}
public abstract class Base<E extends AbstractEntity> {
...
public void doSomething(E entity) {
String street = "";
//Check if the generic entity has a "street" or not.
// If a Person arrives: then the real street should appear
// If a Car arrives: then an empty string would be needed
if (entity instanceof Person) {
Person p= (Person) entity;
street=p.street;
} else if (entity instanceof Car) {
//...
}
logger.trace("Entity name: {}", street);
}
}
如果不是这种情况,那么你将不得不使用反思:
try {
Field field = entity.getClass().getField("street");
street = (String) field.get(entity);
} catch (NoSuchFieldException ex) {
//This entity has no street field
}
答案 2 :(得分:0)
不,您不可能访问类方法中定义的局部变量。编译器不保留名称。
如果属性/字段被定义为类级别属性,那么您可以像@Landei提到的那样访问它们。
答案 3 :(得分:0)
您可以使用反射来检查该字段是否存在:
public void doSomething(E entity) {
String street = "";
Class<?> entityClass = entity.getClass();
// getDeclaredField would allow to see non-public members
Field streetField = entityClass.getField("street");
// you should check the type of the filed here !
logger.trace("Entity name: {}", streetField.get());
}
有关详细信息,请参阅http://docs.oracle.com/javase/tutorial/reflect/index.html。
然而,使用带有反射的仿制药看起来像是一种气味,我建议重新考虑你的设计,以确保没有别的办法!