[英]Why does instanceof seem to work in a static generic function sometimes?
問候。 這是我在本網站的第一篇文章。
我以為是因為類型擦除 ,所以不能期望下面的代碼可以編譯,實際上,它不能在早期版本的Eclipse上編譯。 我的理解是instanceof是一個運行時運算符,並且不知道在運行時會被編譯掉的泛型類型:
public static <E extends Comparable<? super E>>
void SampleForQuestion(E e)
{
if ( !(e instanceof String) )
System.out.println("I am not a String");
else
System.out.println("I am a String");
}
但是,我很驚訝地看到您的一個線程實際上在答案中包含了這樣的代碼,而我最新的Eclipse(Windows上的JVM 1.6 rev 20上的Galileo)對此非常滿意,並且它也可以工作。 (我確實注意到有人說它可以在Eclipse上運行,但不能在該線程的另一個IDE / JDK中運行,但不記得具體細節。)
有人可以解釋它為什么起作用,更重要的是,因為我必須指導我的學生,是否應該期望它將來能起作用?
謝謝。 (我希望代碼格式正確通過-從我的角度看,它看起來正確地縮進了,並且沒有制表符。)
擦除的是E
實際上,您不能執行if (e instanceof E)
,因為類型參數E
被刪除了。 但是, String
不是參數化類型, e
確實具有運行時類型,因此if (e instanceof String)
可以正常工作。
instanceof
運算符 RelationalExpression: RelationalExpression instanceof ReferenceType
instanceof
運算符的RelationalExpression
操作數的類型必須是引用類型或null
類型; 否則,將發生編譯時錯誤。instanceof
運算符后面提到的ReferenceType
必須表示一個引用類型。 否則,將發生編譯時錯誤。 如果在instanceof
運算符 之后提到 的ReferenceType
不表示可驗證的類型 (第4.7節) ,則是編譯時錯誤 。
String
是可更改的類型。 E
不是。
由於在編譯過程中會擦除某些類型信息,因此並非所有類型在運行時都可用。 在運行時完全可用的類型稱為可更改類型。 僅當以下條件之一成立時,類型才是可更改的:
- 它指的是非泛型類型聲明。
- 這是一個參數化類型,其中所有類型參數都是無界通配符
- 這是原始類型。
- 它是原始類型。
- 它是一種數組類型,其組件類型是可更改的。
instanceof
和.class
文字是可以在新代碼中使用原始類型的兩個例外 很好 接受E e
的方法被編譯為Comparable e
,但這並不能防止對運行時存在的類型進行檢查(示例中為String
)。 您不能執行的操作是檢查ArrayList<String>
(或您自己的類的通用專業化),因為ArrayList
類型在運行時存在,但ArrayList<String>
不存在。 因此,人們使用黑客手段,例如檢查列表的第一個元素。
小寫的e是一個對象,每個對象都有它的類型。 您可以在任何對象上檢查instanceof。 閱讀不同名稱的代碼,將更容易獲得:
public static <E extends Comparable<? super E>>
void SampleForQuestion(E paramObject)
{
if ( !(paramObject instanceof String) )
System.out.println("I am not a String");
else
System.out.println("I am a String");
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.