2016-09-08 73 views
3

讓我們說我有: public class Animal{..}Java泛型延長

public class Cat extends Animal {...}

public MakeNoise(Class<? extends Animal> animal1, 
       Class<? extends Animal> animal2){..} 

爲什麼MakeNoise(new Animal(),new Animal())不編譯?

MakeNoise(new Cat(),new Cat())確實編譯。

有沒有什麼辦法來解決這個問題,而不添加接口動物做:

Class<? extends AnimalInterface> 
+0

相同的原因。所以你的方法必須被稱爲'MakeNoise(Animal.class,Animal.class)',可能不是你想要的。它應該是'makeNoise(動物動物1,動物動物2){...}'(也請注意小寫的'm'-閱讀Java編碼約定)。除此之外,可能有一個重載方法接受'Cat',因此允許'MakeNoise(new Cat(),new Cat())'。 – Thomas

+0

我知道 - 我有一個很大的應用程序,並希望避免在這裏進行大的重構。任何想法如何做到這一點? – Bazuka

+1

你的方法簽名似乎是錯誤的(你可能想傳入實例而不是類定義),因此你需要重構一些。 – Thomas

回答

5

爲什麼MakeNoise(new Animal(),new Animal())不編譯?

因爲new Animal()創建Animal不是Class實例的實例。實際上,Class<? extends Animal>指的是Class的實例,在處理Animal的實例時,它是Animal類的子類型。

你所努力實現的,而這樣的:

public MakeNoise(Animal animal1, Animal animal2){..} 

或者假設MakeNoise是一個類,你可以定義你的類定義仿製藥未來:

public class MakeNoise<X extends Animal, Y extends Animal> { 
    public MakeNoise(X animal1, Y animal2){..} 
} 

然後你會能打電話

MakeNoise makeNoise1 = new MakeNoise(new Cat(), new Cat()); 
MakeNoise makeNoise2 = new MakeNoise(new Animal(), new Animal()); 

如果MakeNoise i本該是一個方法(如果因此在你的問題中錯字,因爲沒有返回類型),你也可以在你的方法定義定義泛型類型,你可以在下面的例子中看到:

<X extends Animal, Y extends Animal> void MakeNoise(X animal1, Y animal2) {...} 

while MakeNoise(new Cat(),new Cat()) does compile。

不能編譯無論是因爲你想在課堂上,而不是實例通過前面

+0

確實makeNoise是一種方法。我是否應該在課堂上宣佈X,Y? – Bazuka

+1

如果您只需要方法中的泛型類型,則不需要。如果您需要在類中定義泛型類型,請不要在方法上重新定義泛型類型,否則即使在兩個地方使用X和Y,編譯器也不會將其視爲相同的泛型類型 –