2014-02-21 120 views
0

有没有办法来检查一个字段是否存在一个泛型类?有没有办法检查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); 
    } 

} 
+3

这可以用反射来完成,但我真的认为你应该重新考虑你的设计。也许你可以做一些基于接口的东西? – Keppil

回答

4

我没有看到使用反射的其他方式。如果是这样的(未测试):

try { 
    Field field = entity.getClass().getField("street"); 
    if (field.getType().equals(String.class) { 
     street = (String) field.get(entity); 
    } 
} catch (NoSuchFieldException ex) { 
    /* ignore */ 
} 

如果你有超过类型层次结构的控制,你可以作出这样HasStreetgetStreet()方法的接口,并让与街道的实体实施。这将更清洁:只需检查该接口是否已实施,然后投射并调用该方法。

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 
} 
0

不,您不可能访问类方法中定义的局部变量。编译器不保留这些名称。

如果属性/字段被定义为类级属性,那么您可以按照@Landei提到的方式访问它们。

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

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

相关问题