亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

繞過java中靜態方法的早期綁定

繞過java中靜態方法的早期綁定

至尊寶的傳說 2024-01-05 09:59:01
我有一個 AbstractBaseRepository。我所有的存儲庫都從這個類擴展。我創建了另一個類 RepositoryFactory 來創建 Repository 的任何實例。由于靜態方法的早期綁定,我面臨問題。public abstract class AbstractBaseRepository {    public static <T extends AbstractBaseRepository> T getNewInstance(EntityManagerFactory entityManagerFactory) {        throw new RuntimeException("Override and provide valid initialization");    }    ...}public class RepositoryFactory {    public static <T extends AbstractBaseRepository>  T getRepository(Class<T> cls) {               return T.getNewInstance(entityManagerFactory);    }    ...}一個示例子類public class DeviceModelRepo extends AbstractBaseRepository {    public static DeviceModelRepo getNewInstance(EntityManagerFactory entityManagerFactory) {        return new DeviceModelRepo(entityManagerFactory);    }    ...}每當我使用 AbstractBaseRepository 的有效子類調用 getRepository() 時,都會引發運行時異常。這是由于靜態方法的早期綁定造成的。在編譯時, getNewInstance 與 AbstractBaseRepository 綁定,而不是在運行時與類的實際類型綁定。有什么好的解決辦法嗎?
查看完整描述

2 回答

?
茅侃侃

TA貢獻1842條經驗 獲得超21個贊

我的第一個建議是使用 Spring。獲取使用某個接口創建的所有 bean 的列表非常容易。

另外,如果您將 Repository 實例視為一種“插件”,您可能會看到 Java 的 ServiceLoader 類如何提供幫助。

另外,另一種方法是在工廠中使用 switch 語句并為每種情況創建實例,而不是在 Repository 子類上使用靜態方法。

最后,我不推薦反射解決方案,但有一些方法可以根據類的名稱加載類并反射性地創建新實例。

但重寫靜態方法是不可能的。


查看完整回答
反對 回復 2024-01-05
?
撒科打諢

TA貢獻1934條經驗 獲得超2個贊

通過查看您的代碼,我了解到您希望擁有 AbstractBaseRepository 的不同實現,例如 DeviceModelRepo。然后你需要一個工廠類來創建AbstractBaseRepository的具體實現的實例。這里的主要問題是您嘗試覆蓋永遠無法覆蓋的靜態方法,但子類將隱藏父實現。請不要使用靜態方法進行覆蓋。您可以按如下所示更改您的實施,此問題將得到解決。


public abstract class AbstractBaseRepository {

    public AbstractBaseRepository(EntityManagerFactory entityManagerFactory){

        ...

    }

    //removed method getNewInstance(EntityManagerFactory entityManagerFactory) 

    ...

}

然后是子類的下面的實現。


public class DeviceModelRepo extends AbstractBaseRepository {


    public DeviceModelRepo(EntityManagerFactory entityManagerFactory) {

        super(entityManagerFactory);

        ...

    }

    //removed method getNewInstance(EntityManagerFactory entityManagerFactory) 

    ...

}

現在我為您提供工廠類的兩個實現。一是每個實現都有不同的方法,例如 getDeviceModelRepository()。另一種解決方案是使用反射并通過傳遞實現存儲庫類來獲取存儲庫實例。


public class RepositoryFactory {

    //Solution-1, create separate method for each of repository like below

    public static AbstractBaseRepository getDeviceModelRepository() {       

        return new DeviceModelRepo(entityManagerFactory);

    }

    //Solution-2, use reflection to get instance of specific implementation

    //of AbstractBaseRepository

    public static <T extends AbstractBaseRepository> T 

        getRepository(Class<T> repoClass) throws Exception{


        return repoClass.getConstructor(EntityManagerFactory.class)

            .newInstance(entityManagerFactory);

    }

    ...

}

使用反射解決方案,您可以獲得存儲庫實例,如下所示。


RepositoryFactory.getRepository(DeviceModelRepo.class)


查看完整回答
反對 回復 2024-01-05
  • 2 回答
  • 0 關注
  • 167 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號