1 回答

TA貢獻(xiàn)1865條經(jīng)驗(yàn) 獲得超7個贊
在Java中,類的靜態(tài)變量是在運(yùn)行時還是在編譯時創(chuàng)建的?
Java 在編譯時沒有“創(chuàng)建”變量,如果創(chuàng)建意味著分配和初始化。它們都是在運(yùn)行時創(chuàng)建的。它們是否static
與何時分配static final
無關(guān)。
但我有點(diǎn)期望最終的靜態(tài)變量 PI 將在編譯時創(chuàng)建(因此它將被“嵌入”在 .class 文件中),因?yàn)槲艺J(rèn)為這會有更好的性能......
這不是它在 Java 中的工作方式。當(dāng)類文件被“編譯”時,它們實(shí)際上主要是被編碼的??隙ㄓ幸恍┕ぷ饕呀?jīng)完成,但我們認(rèn)為編譯的超大比例(就 C 等語言而言)是在運(yùn)行時發(fā)生的。當(dāng)我們查看優(yōu)化和內(nèi)聯(lián)時尤其如此。
如果可能的話,編譯器會做一些前期工作,例如能夠提前預(yù)先計(jì)算字段(靜態(tài)或?qū)嵗┑闹?。例如,如果你像下面這樣定義你的字段,那么乘法將在編譯時完成:
private long timeoutMillis = 10 * 24 * 3600 * 1000;
對于 s 也是如此,String
如果可能,編譯器會將常量字符串附加在一起。以下內(nèi)容在運(yùn)行時不使用 a StringBuilder
,而是String
在編譯時創(chuàng)建一個:
private static final String DEFAULT_HEADER = "A long headers that is " + "broker into two lines\n";
但是,在這兩種情況下,字段( thelong timeoutMillis
和 the String DEFAULT_HEADER
)的分配和初始化都是在運(yùn)行時完成的。
如果靜態(tài)變量和最終靜態(tài)變量都在運(yùn)行時創(chuàng)建,那么在 Main 的第一個版本中,MyClass 類的兩個靜態(tài)變量(實(shí)例和 PI)都不會創(chuàng)建。
在您的示例中,第一次加載static
類時分配和初始化字段(final
或不) 。因此,在您的第一個or字段中,永遠(yuǎn)不會像您提到的那樣創(chuàng)建。在你的第二個例子中。一旦被引用,類文件將被加載并創(chuàng)建字段。Main
instances
PI
static
MyClass
static
添加回答
舉報(bào)