2016-10-01 44 views
-3

之前,我的代碼是:確切行爲

class Dog 
{ 
    public static int i=6; 
} 

public class Cat 
{ 
    public static void main(String[] arg) 
    { 
    System.out.println(Dog.i); 
    } 
} 

它執行的很好,但是當我從我的代碼刪除類「狗」,並重新編譯並運行,它給了相同的答案:6.

所以,我的問題是:即使我沒有Dog類在我的代碼中,變量Dog.i來自哪裏,爲什麼?

+1

如果您從'System.out.println'行刪除'Dog.',代碼不再編譯。 –

+0

我猜你忘了保存 –

+2

請僅使用*斜體*和**粗體**作爲實際重點,而不是隨機將它們應用於整個段落。 –

回答

-1

如果您從該System.out.println行刪除Dog.,代碼不再編譯。我會假設你已經從你的Cat類不放過extends Dog

class Dog 
{ 
    public static int i=6; 
} 

public class Cat extends Dog // <===== Note 
{ 
    public static void main(String[] arg) 
    { 
    System.out.println(Dog.i); 
    } 
} 

如果是這樣,原因i解決是CatDog,並在代碼中Dog類或其子類如Cat(對於publicprotected成員),由Dog定義的靜態標識符在範圍內。你不需要限制他們(儘管這樣做可以幫助清晰)。

+0

我不確定這是一個答案,也許假設「作者的意思」 –

+0

@JacekCz:這是什麼適合OP描述的症狀,所以我很確定。如果事實證明我錯了,我會刪除它。 –

+0

是的,你的程序是專業正確的(也許是非自然的繼承),我懷疑只在「教誨」水平 –

0

您沒有刪除Dog.class文件。否則,編譯將是不可能的。

+0

我懷疑OP只是重新'javac'。由於'Cat.class'比'Cat.java'更新,因此可能不會重新編譯。 –

+1

@PeterLawrey我對猜測沒有多大興趣,但是'javac'總是重新編譯特別命名的文件,打開命令行, – EJP

0

javac編譯器爲數不多的優化之一是不斷內聯。這意味着在編譯時已知的任何原始常量都可以插入到位。這意味着你的代碼是一樣的

public class Cat 
{ 
    public static void main(String[] arg) 
    { 
    System.out.println(6 /*Dog.i*/); 
    } 
} 

可以刪除Dog.*和只要你不重新編譯Cat它會正常運行。注意:再次運行javac並不意味着將重新編譯所有內容,javac將檢查.class文件是否永遠不會是.java文件。

此外,如果您刪除Dog.java這不會刪除Dog.class而您只需稍後重新編譯此類。

+0

這不符合描述*「當我從代碼」*中刪除類「Dog」時。沒有注意到它沒有第二次編譯(你對EJP的答案發表評論),並且擁有'extends Dog',但沒有。 –

+0

@TJCrowder我不明白'extend Dog'是如何產生任何區別的,因爲常量的類名包含'Dog.i'當OP說他刪除了類「Dog」時,它並不清楚這意味着什麼'Dog.java',也沒有'Cat.class'被刪除以確保它被重新編譯。 –

+1

由於「刪除的狗」,我想他是從'System.out.println'行開始的,考慮到問題其餘部分的內容以及它如何討論想知道'i'來自哪裏。但從根本上來說,這個問題是不值得你的時間,我的,或EJP的,直到/除非澄清。 :-) –