4 回答

TA貢獻(xiàn)1770條經(jīng)驗(yàn) 獲得超3個(gè)贊
您詢問的方法是main(),如下所示(我將類和方法編輯到最低限度)。正如您所發(fā)現(xiàn)的,它有效。
class Box<T> {
public static void main(String[] args) {
// do something
}
}
該方法很好,因?yàn)樗c泛型類型沒有關(guān)聯(lián)T。這里,main是一個(gè)靜態(tài)方法,這意味著它在沒有對(duì)象實(shí)例的情況下被調(diào)用。
泛型不適用于靜態(tài)方法(或字段),但上面的示例并沒有這樣做。這是一個(gè)不同的示例,嘗試定義一個(gè)也使用的靜態(tài)方法T(但它不起作用):
class Box<T> {
public static void bar(T args) {
// do something
}
}
這個(gè)例子是一個(gè)靜態(tài)方法,將在沒有對(duì)象實(shí)例的情況下被調(diào)用 - 就像這樣:Box.bar(someArgs)- 但這是無效的。如果不首先創(chuàng)建某個(gè)泛型類型的實(shí)例Box,編譯器如何知道它T是什么?
可以定義一個(gè)靜態(tài)方法來使用泛型類型,但該方法完全獨(dú)立于T您的示例。對(duì)于某些單獨(dú)的泛型類型,有一種方法可以做到這一點(diǎn)X:
class Box<T> {
public static <X> void foo(X input) {
// do something
}
}
你可以這樣稱呼它:Box.foo("");

TA貢獻(xiàn)1828條經(jīng)驗(yàn) 獲得超6個(gè)贊
您不是“在這里執(zhí)行課程”。main()
相反,您正在類中執(zhí)行靜態(tài)方法。允許您這樣做的原因是類型擦除。泛型類型僅在編譯代碼時(shí)強(qiáng)制執(zhí)行。在不聲明任何引用或創(chuàng)建Box<T>
編譯器實(shí)例的情況下,沒有理由檢查泛型類型。當(dāng)您運(yùn)行程序時(shí),由于類型擦除,解釋器對(duì)通用代碼一無所知,因此它愉快地運(yùn)行程序。

TA貢獻(xiàn)1946條經(jīng)驗(yàn) 獲得超4個(gè)贊
Java 與 C 不同。不存在“對(duì)于每一個(gè)可以想象到的 T/代碼庫中實(shí)際使用的每一個(gè) T 都有一個(gè) Box 類的變體”。只有盒子。例如:
new Box<String>().getClass() == new Box<Integer>().getClass() // this is true
您不會(huì)加載單獨(dú)的類等。
這確實(shí)有一些副作用: 不可能從String
變量 x 中導(dǎo)出: Box<?> x = new Box<String>();
- 該信息現(xiàn)在已經(jīng)消失了。這稱為擦除。
實(shí)際上,泛型幾乎完全是編譯器想象的產(chǎn)物。這就像在打字稿中輸入信息等:它在編譯時(shí)就存在,編譯器將使用它來告訴您類型未對(duì)齊(編譯器錯(cuò)誤),但是一旦編譯器接受所有信息,它就會(huì)被編譯為一種在運(yùn)行時(shí)完全消除此信息的形式*。
這就是為什么上面的代碼可以毫無抱怨地工作:你有一個(gè)靜態(tài)方法,<T>
這里甚至不存在。
讓我們放大一下 get 和 set 方法以及 't' 字段: 它們完全是這樣的:private Object t; public void set(Object o) { this.t = t; } public Object get() { return t; }
只有一個(gè)例外:如果在編譯時(shí),它沒有意義,編譯器將拒絕編譯它。此外,對(duì)于呼叫的任何呼叫者get
,都會(huì)默默地包含一個(gè)演員表。
*)不完全是;簽名中泛型的任何使用,因此,字段的類型、類自己的定義、和implements
行extends
以及方法的返回類型或參數(shù)類型中,都不會(huì)被消除,但它就像是對(duì)VM:VM不關(guān)心這些東西;它存在的唯一目的是,如果您調(diào)用javac
類路徑上的某些內(nèi)容,javac 在與這些成員交互時(shí)知道泛型是什么。就這些。

TA貢獻(xiàn)1831條經(jīng)驗(yàn) 獲得超10個(gè)贊
Java 內(nèi)部的泛型旨在為您的對(duì)象提供編譯時(shí)類型安全性。對(duì)于您的情況,它根本不訪問類中方法t內(nèi)部的變量。main()這樣java就會(huì)愉快地編譯并運(yùn)行程序了。
如果您Box在main()方法內(nèi)實(shí)例化該類:
Box b = new Box(); // this is will produce "unsafe operations" note
b.set("this is the string");
System.out.println(b.get().getClass().getName());
根據(jù)最后一個(gè)變量賦值,您將在此處獲得一個(gè)字符串。
添加回答
舉報(bào)