有没有办法检查Generic类是否存在字段?

时间:2014-02-21 08:33:40

标签: java generics field

有没有办法检查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);
    }

}

4 个答案:

答案 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

然而,使用带有反射的仿制药看起来像是一种气味,我建议重新考虑你的设计,以确保没有别的办法!