2013-10-08 38 views
1

static方法只能調用同一類的靜態方法/字段。問題:靜態約束

  1. 爲什麼非靜態方法/域不得提供給static因爲一旦static方法被調用,然後JVM創造了一個對象,它可以訪問類的其他地方,如果JVM允許?

  2. 爲什麼static方法允許來自其他類的非靜態方法的對象。強加限制他們只能訪問其他類的static,並讓static訪問同一類的非靜態成員會導致任何區別?

+0

我希望這一大堆downvotes帶有一些很好的建議。 – Rorschach

+0

'一旦靜態方法被調用,JVM就爲它創建了一個對象'沒有JVM不創建對象。 –

+0

除非您有對象,否則您無法訪問任何內容。你只是無法訪問它。 – Rorschach

回答

2

一次的靜態方法被稱爲比JVM已經創建了一個對象 它

這是不正確的。可以調用靜態方法而無需創建定義靜態方法的類的對象(記住public static void main())。

爲什麼靜態方法()允許來自其他類的非靜態方法的對象。

這是因爲可以存在other classe實例不論類定義的靜態方法的對象(其訪問的other class)是否存在。

結賬this link獲得進一步的見解。

3

以下是靜態方法和字段的java語言規範。希望它能幫到你

8.3.1.1。靜態字段

如果一個字段被聲明爲靜態,那麼無論該類最終可能創建多少個實例(可能爲零),該字段都只有一個字符。一個靜態字段,有時稱爲類變量,在類被初始化時被體現(§12.4)。

未聲明爲靜態的字段(有時稱爲非靜態字段)稱爲實例變量。只要創建了一個類的新實例(第12.5節),就會爲該類或其任何超類中聲明的每個實例變量創建與該實例關聯的新變量。

8.4.3.2。靜態方法

聲明爲靜態的方法稱爲類方法。

在類方法的標題或正文中使用任何周圍聲明的類型參數的名稱時發生編譯時錯誤。

總是調用一個類方法而不參考特定的對象。嘗試使用關鍵字this(第15.8.3節)或關鍵字super(第15.11.2節)引用當前對象是編譯時錯誤。

未聲明爲靜態的方法稱爲實例方法,有時稱爲非靜態方法。

對於一個對象,總是調用一個實例方法,該方法將成爲在方法體執行過程中this和super所引用的關鍵字的當前對象。

+0

我的問題是,爲什麼這些規則是這樣制定的,如果我已經做出了變化,那麼它會使Java變得更加美麗。 – Rorschach

+2

我認爲黑鳥知道這一點...他問「爲什麼?」 – TheLostMind

+0

那麼爲什麼選擇一種特定的風格沒有中央資源庫。但是你可以通過JSR並從那裏獲得一些提示。 – Jabir

3

非靜態方法有一個隱式this目的是可以在其他非靜態方法

靜態方法調用不能隱式調用非靜態方法,因爲它沒有對象隱含地使用。沒有什麼可以阻止你明確地使用對象來調用方法。

例如

class Main { 
    public static void main(String... ignored) { 
     new Main().nonstatic(); // calls non-static method 
    } 

    public void nonstatic() { 
     nonstatic2(); // calls non-static object with implicit reference to "this" 
    } 

    public void nonstatic2() { 
     staticMethod(this); 
    } 

    public static void staticMethod(Main main) { 
     main.nonstatic3(); // static calls non-static with explicit object. 
    } 

    public void nonstatic3() { 
    } 

靜態方法只能調用靜態方法/來自同一類的字段。

這是不正確的,如示例所示。

爲什麼非靜態方法/域不得提供給靜態的,因爲一旦靜態方法被調用,然後JVM創造了一個對象,

的JVM可以自動地創建一個對象,但這不太可能是有用的,尤其是如果對象沒有默認構造函數。

如果JVM允許,可以訪問類的其他部分嗎?

它可以允許,但不應該恕我直言,因爲這會比有用的更混亂。

爲什麼靜態方法允許來自其他類的非靜態方法的對象。

靜態方法允許來自所有類的對象,而不僅僅是其他類。

強制限制他們只能訪問其他類的靜態並讓靜態訪問同一類的非靜態成員會導致任何區別?

區別在於你沒有隱式類的實例這是靜態方法的全部要點。

如果您想要一個隱式實例,您可以使用非靜態方法。

+0

創建對象與創建其他類的對象並訪問它是同義詞。它的幫助,但仍然沒有清除我的懷疑。 – Rorschach

+0

@Blackbird我已經依次回答了每個問題。我不清楚混淆是從哪裏來的。靜態與非靜態比您想象的要簡單得多。 –

1

爲什麼非靜態方法/字段不能用於靜態,因爲一旦調用了靜態方法,JVM就爲它創建了一個對象,如果JVM允許,它可以訪問其他類的部分?

如果允許靜態方法訪問非靜態方法,這意味着將調用一個實例級方法,而不使用該類的實例。那麼你將如何重寫該方法?重寫將查看調用/調用該方法的對象,以及是否從靜態方法直接調用非靜態(實例)方法,哪些對象正用於調用?

並從設計的角度來看 -

假設你有一個叫做Dog的類。每隻狗都吃,睡覺等。但要記住的最重要的事情是所有這些事情都是特定於Dog實例的。每個對象的狀態應該通過實例級別的方法來訪問 - 這就是封裝的全部要點。如果你說Dog.sleep()。哪隻狗應該睡覺?

+0

這聽起來很合理,我想根據這個做一個程序,我會再來找你。 – Rorschach

+1

這確實是一個很好的問題...從我+1:P – TheLostMind

2

爲了理解爲什麼static方法不能調用non static方法或訪問non static變量,你需要了解對象之間的diffeerence。

Java是一種面向對象的語言。首先定義一個,它包含狀態(實例變量)和更改狀態(實例變量)的方法。 但是班級不是對象。它只是一個用於創建對象的模板,您可以使用new關鍵字(創建類的一個實例)。 創建對象後,其變量處於初始狀態,然後調用讀取或更改對象狀態的方法。這些變量和方法是non static,因爲它們需要一個類的對象實例。

但是,在一個類中,您可以定義一個不讀取或更改狀態的方法。方法的行爲完全不依賴於實例變量。 這樣的方法可以聲明爲靜態的,這意味着不需要該類的實例來運行該方法。

你直接調用一個靜態方法上一個類(沒有引用的對象):

MyClass.staticMethod();//will not read or change any state, because there is no object here 

你也可以調用的對象上的靜態方法,但不會訪問對象的狀態,因爲其行爲確實不依賴也不改變對象的狀態。呼籲obj.staticMethod();相同MyClass.staticMethod();

//Create an instance of a MyClass 
MyClass obj = new MyClass(); 

//will not read or change any state of obj. 
obj.staticMethod(); 

然而要注意的靜態方法並非完全無狀態的,他們仍然可以讀取或更改靜態varibables的狀態。

還要注意,在Java中,你不能重寫靜態方法(不像在Delphi中) - 如果你認爲子類需要覆蓋靜態方法,不要聲明方法爲靜態方法。 因此,如經驗法則在特殊用途的工具類中聲明靜態方法,無論如何不需要實例,例如java.lang.Math,否則 不會將方法聲明爲靜態,即使它沒有讀取或更改對象的狀態,因爲您可能需要稍後重寫它。