[英]Retrieve Class instance of Generic Type without taking the Generic as an input
我有一堂課:
public abstract class BaseDaoImpl<T extends BaseModel> implements BaseDao<T> {
}
我還使用注釋來生成 SQL 查詢(由於各種原因,我無法使用諸如 hibernate 之類的框架),例如 @Table & @Column
我希望能夠檢索<T extends BaseModel>
.class
實例,而不必將T
作為方法的輸入。
我想簡單的替代方法是創建一個方法:
public void set(Class<T> clazz){}
但是,如果可能的話,我想避免這種情況,以盡可能簡化我的代碼。 這可能嗎?
不幸的是,由於類型擦除,這是不可能的:您必須強制您的類在運行時提供元信息。 我會做這樣的事情(來自一個大型真實項目的改編片段)。
public abstract class AbstractBaseDao<T extends BaseModel> implements BaseDao<T>{
public abstract Class<T> getType();
}
class ConcreteModel extends BaseModel {/*...*/}
class ConcreteDao extends AbstractBaseDao<ConcreteModel> {
@Override
public Class<ConcreteModel> getType() {
return ConcreteModel.class;
}
}
另一種方法是像這樣定義自定義注釋:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Type {
Class value();
}
interface BaseDao<T extends BaseModel> { }
@Type(ConcreteModel.class)
public class ConcreteDao implements BaseDao<ConcreteModel> { }
...並在某些處理器中為您的 DAO 使用它,但這將需要一些額外的基礎結構代碼來注冊所有帶注釋的類。 而且 - 再次 - 您不能限制注釋內的類型界限。
雖然使用反射有點代碼味道,但你可以得到你需要的信息:
Class<T> modelImplementationClass = (Class<T>)
((BaseModel)this.getClass().getGenericSuperclass())
.getActualTypeArguments()[0];
反射是一種 Java API,允許您在運行時訪問或修改方法、類、接口的行為。
通常應該避免反射,因為它非常慢並且通過揭示內部實現細節來破壞抽象。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.