2013-06-06 94 views
0

我是一些C++的全新Java代碼,我想知道當我調用靜態方法或訪問靜態字段而沒有該類的實例時會發生什麼:沒有對象的Java和靜態成員/函數訪問

class Foo { 
    public final static Scanner _input = new Scanner(System.in); 
} 

class Bar { 
    public final static Scanner _input = new Scanner(System.in); 
} 

... 

SomeCode[Foo._input.nextInt()]; 

我無法想象一個臨時對象被創建,但不知道。 謝謝

回答

4

我想知道,當我調用靜態方法或不具有類

它只是訪問領域的實例訪問靜態字段會發生什麼?就這麼簡單。它不會創建一個Foo的實例 - 它不需要。

該字段不與任何類型的實例關聯 - 它與類型本身相關聯。基本上這就是Java中的static。你應該試着忽略C++中static的任何含義,恐怕這有些不同。

有一點需要注意的是在設計Java時有效的問題 - 你可以通過引用訪問靜態成員,但這並不意味着你期望的。例如:

Foo foo = null; 
Scanner scanner = foo._input; 

看起來像它會爆炸與NullPointerException - 但事實並非如此。該代碼相當於:

Foo foo = null; 
Scanner scanner = Foo._input; 

儘可能避免第一種形式的代碼是值得的。這可真令人誤解,特別是當你調用方法 - 它看起來通話依靠實例(可以是多態的),但實際上這兩個是不正確:(

+0

+1非常快:) – Bohemian

1

臨時對象被創建?

static關鍵字用於創建屬於類的字段和方法,而不是類的實例。

Heavily recommending

1

static領域與關聯它們的解析是在編譯時完成的;靜態變量(和靜態初始化塊)的初始化是在JVM加載類時運行的。

至於如何訪問這些變量(或方法),你可以或者像你一樣使用類名,但是Java也允許你使用類的實例變量來實現這一點,包括null

所有這三個表達式允許訪問Foo類名爲bar一個靜態變量(提供bar是由主叫方可見):

Foo.bar;   // using the class name 
new Foo().bar;  // using an instance 
((Foo) null).bar; // using a null instance 
+1

「靜態實例變量」是一種自相矛盾的說法。你的意思是「靜態字段」 - 重點是它們不與實例關聯。 –

+0

哎呀,是的,對不起......修正了。 – fge

+0

不,這三行*不是*等價的 - 第二行創建了「Foo」的實例,但其他行不行。 –

1

我無法想象一個臨時對象創建,

沒有。您可以使用該類對象來調用該方法。

+0

「類對象」不清楚。我認爲class類的實例更好 – shevchyk

1

您已使用static和final關鍵字,兩者都有不同的含義。

當您聲明任何使用static關鍵字的變量,然後將其聲明爲類變量,意味着它對該類的所有實例都是通用的。使用類名訪問不需要使用實例。

E.g.

Class Bycicle 
{ 
    static String Type ='exercise'; 
    String Owner; 

} 

如果你創建這個類,那麼業主的1O副本將創建10個實例,而式仍將只有一個共同的副本,所有10個對象。一個對象更改類型值,然後它將影響所有其他對象。

如果你聲明靜態與final,那麼它對所有人都是通用的,並且在編譯時聲明和初始化後也不允許改變。

去這裏的更多有趣的細節click here