2012-11-14 73 views
0

神父以下通用類,有一個行R = G編譯錯誤: 類型不匹配:不能從GenericTest1 <整數>轉換爲GenericTest1 <數> 怎樣纔可以解決嗎?如何解決Java中的r = g編譯問題?

public class GenericTest1<T> { 
    private T t; 

    public GenericTest1(T t) { 
     this.t = t; 
    } 

    public void set(T t) { 
     this.t = t; 
    } 

    public T get() { 
     return t; 
    } 

    public static void main(String[] args) { 
     GenericTest1<Integer> g = new GenericTest1<>(6); 
     GenericTest1<Number> r = g; <==here 
    } 
} 
+2

類型轉換它'GenericTest1 R =(GenericTest1 )克; ' –

+1

@ShashankKadne類型轉換將不起作用 - 它仍然不能編譯。 –

回答

1

的這裏的誤解是,GenericTest1<Number>GenericTest1<Integer>一個超類。它不是,所以你必須單獨施放每個成員。

1

當涉及到泛型編程時,這是一個常見的誤解。這裏兩個具體類型GenericTest1<Integer>GenericTest1<Number>沒有任何關係。唯一通用的部分是Object的子類。

1

兩個類,通用測試<號>和通用測試<整數>不分配兼容。你甚至不能施放它們。但是,如果你不介意複製的對象,你可以做到以下幾點:

添加一個拷貝構造函數到類:

public GenericTest1(GenericTest1<? extends T> other) { 
    this.t = other.t; 
} 

,然後複製對象:

public static void main(String[] args) { 
    GenericTest1<Integer> g = new GenericTest1<>(6); 
    GenericTest1<Number> r = new GenericTest1<Number>(g); 
} 
0

GenericTest1<Integer>GenericTest1<Number>不兼容,您不能在它們之間投射!但是,如果你不希望暴露整數,你可以使用綁定:

GenericTest1<? extends Number> r = g; 

r是真正的一個GenericTest1<Integer>,但聲明允許只數的訪問。由於非特異性T型的,你不能叫set()(OK,工程用NULL),但你可以使用get()

g.set(Integer.valueOf(1)); // OK 
r.set(Integer.valueOf(1)); // compile ERROR 
if (r.get().intValue() == 1) { //OK 
    ... 
} 
+0

通過這樣做,我得到編譯錯誤:類型不匹配:無法從GenericTest1 轉換爲GenericTest1 <?擴展號> –

+0

您使用哪個Java版本? Java 6或7沒有問題。我沒有Java 5了。 –

0

首先,我會在你的類限制可以接受的類型,並介紹方法比較場Number或與其他GenericNumber和這樣定義

public class GenericNumber<T extends Number> { 
    private T number; 
    public T getNumber() { 
     return number; 
    } 
    public void setNumber(T number) { 
     this.number = number; 
    } 
    public void setNumber(T number) { 
     this.number = number; 
    } 
    //constructors 
    public int compareTo(Number n) throws Exception { 
     if((number == null) || (n == null)) 
      throw new Exception("Can't compare null values"); 
     else if(number.doubleValue() > n.doubleValue) 
      return 1; 
     else if(number.doubleValue() == n.doubleValue) 
      return 0; 
     else 
      return 1; 
    } 
    public int compareTo(GenericNumber n) throws Exception { 
     if(n == null) 
      throw new Exception("Can't compare null values"); 
     return compateTo(n.getNumber()); 
    } 
} 

通過這種方法測試實例平等的泛型類轉換成如下條件,你的對象:(r.compareTo(g) == 0)

如果您不想使用此類型的java風格的比較類方法,那麼當然可以對字段進行類型轉換並與=運算符進行比較。

對於你期望的行爲,做出這樣的分配是不對的,因爲GenericNumber<Integer>不是GenericNumber<Number>的子類型,就像我們的直覺暗示的那樣,雖然Integer是Number的子類型。據瞭解,假設你的情況,你想調用一組方法上的GenericNumber<Number>一個實例:

GenericNumber<Integer> i = new GenericNumber<Integer>(); 
Integer ii = 3; 
i.setNumber(ii); 
GenericNumber<Number> n = i;//suppose it will be consumed by compiler 
//in this case it will be tempting to forget about i and use n instead, like in the following lines 
Folat f = 2.5f; 
n.setNumber(f); 
//would be valid because method signature will be 
//public void Number setNumber(Number number) 
//but what actually happens is that you will try to call method of class 
//GenericNumber<Integer> with signature public void Integer setNumber(Integer number) 

正如你看到的,最後一行會產生錯誤,所以你需要使用泛型謹慎。

順便說一句,在當時的太陽,現在甲骨文網站的泛型教程節是值得一遊,即: http://docs.oracle.com/javase/tutorial/java/generics/index.html和/或 http://docs.oracle.com/javase/tutorial/extra/generics/index.html