2015-07-05 62 views
0

我無法理解這段文字來自完全參考 的代碼是這樣的,運行時類型比較在泛型層次結構中的Java

public class Generic 
{ 
    public static void main(String[] args) 
    { 
     SuperClass<Integer> s1=new SuperClass<>(135); 
     SubClass<Double> s2=new SubClass<>(1.35); 
     if(s1 instanceof SuperClass<Integer>) 
     { 
      System.out.println("I am instance of SuperClass"); 
     } 
    } 
} 

class SuperClass<T> 
{ 
    T y; 
    SuperClass(T ob) 
    { 
     y=ob; 
    } 
    T ret() 
    { 
     return(y); 
    } 
} 

class SubClass<T> extends SuperClass<T> 
{ 
    T x; 
    SubClass(T y) 
    { 
     super(y); 
     x=y; 
    } 
} 

根據課文,

if(s1 instanceof SuperClass<Integer>)此行無法編譯,因爲它嘗試將s1與特定類型SuperClass(在本例中爲SuperClass<Integer>)進行比較。請記住,運行時沒有可用的通用類型信息。因此,instanceof無法知道s1是否爲SuperClass<Integer>的實例。

有人可以請解釋我究竟是什麼意思?

+0

明確你難道不明白是什麼? –

+0

@ RedRoboHood - 我認爲只有在運行時纔可以使用泛型類型信息,但是這裏說它在運行時不可用。 –

+0

erasure是所有惡意的根源。 – ZhongYu

回答

2

當你的.java文件被編譯成.class文件,也就是所謂的字節碼,SuperClass<Integer>這段代碼被轉換爲SuperClass。這稱爲類型擦除。所以在運行時沒有關於泛型的信息。

+0

@Amit.rk3-以及如果我編寫SuperClass 會發生什麼,它編譯好,爲什麼? –

+0

@RajMalhotra'?'是'任何'的通配符。所以'SuperClass ''相當於'SuperClass' –

1

泛型信息是一種編譯時功能。它在運行時被擦除。該錯誤是在this section of the Java Language Specification說明:

它是一個編譯時間錯誤,如果操作者instanceof後提到的引用類型不表示引用類型是reifiable(§4.7)。

而一個reifiable類型爲defined爲:

由於某些類型的信息在編譯時擦除,不是所有類型的都可以在運行時。在運行時完全可用的類型稱爲可確定類型

A型是reifiable當且僅當如下條件之一成立:

  • 它指的是一個非通用類或接口類型聲明。

  • 它是一個參數化類型,其中所有類型參數都是無界通配符(§4.5.1)

  • 它是一種原始類型(§4.8)。

  • 它是一種原始類型(§4.2)。

  • 它是一個數組類型(§10.1),其元素類型是可調整的。

  • 它是一個嵌套類型,其中對於由「。」分隔的每個類型T,T本身是可賦值的。

因此,不允許有一個參數化的類型等SuperClass<Integer>作爲參考類型instanceof。另一方面,SuperClass<?>被允許。

1

在引擎蓋下面,有一種叫做的類型擦除發生在使用泛型時。這意味着泛型類型在將程序編譯爲字節碼的過程中轉換爲原始(非泛型)表單。所有類型參數都簡單地變爲Object,並且分配給類型變量的所有值都轉換爲Object。這就是「在運行時沒有可用的通用類型信息」的含義。

的線如

if(s1 instanceof SuperClass<Integer>) 

編譯之後變得

if(s1 instanceof SuperClass) 

。在參數化類型上使用instanceof的問題是在運行時期間,Java VM無法區分諸如SuperClass<Integer>SuperClass<Double>之類的類型。如果編譯器確實允許instanceof與參數化類型一起使用,則前一行也將返回爲SuperClass<Double>,這可能會產生未定義的行爲。

如果你想知道更多,Oracle的網站上有一個更透徹的解釋:https://docs.oracle.com/javase/tutorial/java/generics/restrictions.html#cannotCast

+0

- 謝謝哥們,我懂了 –