簡體   English   中英

檢索 Generic Type 的 Class 實例而不將 Generic 作為輸入

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM