2013-02-28 120 views
8

我需要在java中使用反射。我知道Class clazz會創建一個代表Class對象的變量。但是,我試圖使用forName("aClassName")方法引用String中的Class對象。我的IDE(Eclipse)似乎更喜歡使用Class<?> clazz來聲明變量。我在其他地方多次看到過這種符號。這是什麼意思?Class clazz和Class <?> clazz在java中有什麼區別?

編輯:刪除對三元運算符的引用,因爲它與此問題無關。

+2

這與三元運算符有什麼關係?這裏沒有運營商。 – 2013-02-28 20:06:24

+0

在這種情況下,它不是一個三元運算符,它是一個未綁定的通配符。 – Perception 2013-02-28 20:06:30

回答

22

Class是一個原始類型 - 它基本上是一種泛型類型,你對待就好像你根本不知道泛型一樣。

Class<?>是使用未綁定通配符泛型類型 - 這基本上意味着「Class<Foo>某種類型Foo,但我不知道是什麼。」

同樣可以有通配符界限:

  • Class<? extends InputStream>的意思是「Class<Foo>某種類型Foo,但我不知道是什麼,只要它是InputStream或子類」

  • Class<? super InputStream>的意思是「Class<Foo>某種型號Foo,但我不知道什麼,只要它是InputStream或超級」

又見Java Generics FAQ很多更多信息:

和Java語言規範:

特別是,從原始類型的部分:

原始類型密切相關的通配符。兩者都基於存在類型。原始類型可以被認爲是通配符,其類型規則故意不適用,以適應與舊代碼的交互。歷史上,原始類型在通配符之前;它們首先在GJ中介紹過,並在文章中描述了過去對於未來的安全性:Gilad Bracha,Martin Odersky,David Stoutamire和Philip Wadler在Java編程語言中增加Genericity在ACM Conference on Object-面向對象編程,系統,語言和應用程序(OOPSLA 98),1998年10月。

+0

但是,從技術上講,原始類型和未綁定通配符之間沒有任何區別,是嗎?我的意思是,除了避免編譯器警告和可能增加代碼可讀性。 – Gothmog 2013-02-28 20:13:37

+1

@Gothmog:由於原始類型的處理方式(IIRC),有些情況會影響覆蓋和重載。 – 2013-02-28 20:14:55

+0

非常感謝Jon,非常感謝! – 2013-02-28 20:21:54

0

在一般類型通配符?表示「任何類」(因此Class<?>相同只是Class而是作爲原始類型參數化正確)。

2

首先要認識到的是,在這種情況下,「?」不是三元運算符,但它是Java的泛型實現的一部分,並指出類的類型未指定,因爲其他一些答案已經解釋過。

爲了闡明關於三元運算符的問題,它其實很簡單。

想象一下,你已經if語句如下:

boolean correct = true; 
String message; 

if (correct) { 
    message = "You are correct."; 
} else { 
    message = "You are wrong."; 
} 

您可以重寫與三元運算符(認爲它作爲if-else語句的快捷操作):

message = (correct) ? "You are correct." : "You are wrong."; 

然而,爲了提高代碼的可讀性,除了最簡單的語句之外,最好避免使用三元運算符。

+0

我看到,我的印象是「?」總是被稱爲三元運算符。我現在看到這是不正確的。三元運算符是常用的,還是這是過去更受歡迎的功能? – 2013-02-28 20:25:13

+0

我會說,它仍在使用,但通常可以避免。我仍然看到它現在隨時出現在代碼中,所以知道如何閱讀它是很好的。在極少數情況下,使用更簡潔的陳述可以更清楚地瞭解正在發生的事情。這是我唯一考慮使用if/else的時間。 – yogaphil 2013-02-28 21:19:18

相關問題