2014-02-21 150 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

但是,反射式仿製藥的使用看起來像是一種氣味,我建議重新考慮一下你的設計,以確保沒有別的辦法!

相關問題