簡體   English   中英

Java Generics Hell - 傳遞這個,但它想要類型T

[英]Java Generics Hell - Passing in this but it wants type T

我目前正在開發一個輕量級的通用仿真框架。 目標是允許人們將Simulation和Scenario對象子類化為其特定於域的需求。 仿制葯似乎是實現這一目標的合適方式,但我擔心我可能會陷入仿制葯的地獄。

Sim對象提供對模擬實體的訪問並控制sim(開始/暫停/停止)

Scenario對象允許您使用模擬實體填充Sim。

SIM卡:

public class Sim 
{
  public <T extends Sim> void loadScenario(Scenario<T> scenario)
  {
      reset();
      scenario.load(this);
  }
}

場景:

public interface Scenario<T extends Sim>
{
    public void load(T sim);
}

我們的目標是讓用戶創建一個MySimextends SimMyScenarioimplements Scenario<MySim>為自己的域。

例如MyScenario:

public class MyScenario<MySim>
{
    public void load(MySim sim)
    {
        // make calls to sim.addMySimEntity(...)
    }
}

具體來說,使用上面的代碼, Sim.loadScenarioscenario.load(this)調用給出了錯誤: Scenario類型中的方法load(T)不適用於參數(Sim) 我明白這是因為我正在加載this (它是Sim類型)當需要的是T extends Sim ,這意味着我應該傳遞一個可以是Sim的任何子類型的對象。

有什么方法可以糾正這個問題來實現我想要實現的目標? 或者,它甚至可能嗎? 也許仿制葯不能為我做這件事。

如果它總是成為Sim的子類型,那么為什么不在你的方法中指定它並完成呢? 似乎仿制葯在這里買不到你。

但無論如何,我認為你想要loadScenario

public void loadScenario(Scenario<? extends Sim> scenario)

編輯:好的,現在我實際上想過它,這也無濟於事。 您的loadScenario將通過一個帶有類型參數T的場景,該類型參數為Sim的子類型。 但是你試圖傳遞一個Sim,它不能保證成為Sim的正確子類型。

解決方案是Scenario.load方法需要采用Sim viz:

public interface Scenario<T extends Sim>
{
    public void load(Sim sim);
}

和Sim保持你寫它的方式。 請注意,您的MySim類必須實現此功能,並明確地將其窄化為類型參數。

編輯:另一種方法是在Sim基類中使用靜態方法:

public class Sim
{
    public static <T extends Sim> void loadScenario(Scenario<T> scenario, T sim)
    {
        scenario.load(sim);
    }
}

然而,由於將Sim的實例傳遞給類型為T的類型,因此不能將其作為實例方法,因為Sim不是類型安全的。 通過創建一個也通過Sim的靜態方法,您可以讓編譯器有機會檢查T for Scenario類型參數和T for sim匹配。

我明白這是因為我正在加載它(它是Sim類型)當需要的是T擴展Sim時,這意味着我應該傳遞一個可以是Sim的任何子類型的對象。

號的問題是,accoding的方法規范,你應該通過類的對象T ,這是特定的子類 Sim匹配您的方案-這this不是(至少代碼不能保證它是) 。

但不知道如何解決這個問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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