2014-02-20 55 views
11

雖然這是一個非常基本的代碼,但它似乎在Java中存在根本性的缺陷,或者是我用來運行代碼的Eclipse IDE使用的JVM。爲什麼可以從不同的實例訪問「私有」方法?

該代碼運行,即使它不應該(我認爲)! A.java中的代碼只顯示「你好,我是A!」

這就是:

import java.lang.*; 
import java.util.*; 
class A { 
     private void methodA() {System.out.println("Hello, I am A!");} 
     public static void main(String[] args) { 
     A a = new A(); 
     a.methodA(); } 
} 

我不明白爲什麼,創建一個類的實例後,main()的運行A級在該實例的私有方法成功。是的,主要方法屬於A類,但它不訪問在「this」參考的上下文中當前對象內部的私有方法。實際上,由於它是一個靜態方法,因此它不能從類內部訪問非靜態成員。不是main(),非靜態成員方法只能從中調用methodA(),而在之內。但這是另一個問題,因爲我沒有定義任何非靜態的第二種方法。

現在內視在談到,讓我們回過頭來來看,外視。如您所見,main()嘗試從以外的對象調用methodA併成功!爲什麼不是私人被視爲私人

我拉我的頭髮....

任何人,請回復......

+0

你是什麼意思的「對象外」? – Maroun

回答

16

是的,主要方法屬於類A,但它不是從「this」引用的上下文中訪問當前對象內部的私有方法。

沒關係。這不僅僅是Java使用的可訪問性模型。重要的是編寫代碼的類,而不是它是否訪問同一對象中的成員。

這是非常有用的,否則(例如)使用這兩個類的私有成員實現equals方法將是不可能的。

這可能不是你會如何選擇指定的語言,但它如何指定的Java。有關輔助功能的詳細信息,請參閱JLS 6.6.1。特別是:

否則,如果成員或構造被聲明的私人,則訪問被許可,當且僅如果它發生在頂層類的主體內(第7.6節),其包圍所述成員的聲明或構造函數。

注意protected訪問是略微奇數此處 - SuperClass類的受保護的實例成員只能內​​代碼經由任一​​或進一步的子類的表達來訪問。但它仍然不一定是「相同」的對象。

+1

C#的情況是否如此? –

+3

@Moslem:是的。有一些差異,但基本原則是一樣的。 –

7

private modifer

方法,變量和構造函數被聲明爲private只能內部訪問聲明的類本身。

+3

[鏈接到文檔將會很棒!](http://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html)。 – Maroun

5

private意思是「私人的班級」。不是「私人的實例」。

那是什麼讓像靜態工廠方法實現的東西調用私有構造函數,或equals()compareTo()方法比較同一類對象的私有字段,或拷貝構造函數等

外部類的私有成員也可以訪問來自這個封閉類的內部類,反之亦然。

2

技術上正確的答案後,這裏是我的兩分錢,爲什麼我覺得這是很有道理的實施private這樣:

在我看來最主要的原因是private的方法和屬性存在,是「實現隱藏」。你聲明「不要在我的課外(!)使用這種方法,因爲它可能隨時改變或消失」。因此,禁止課外訪問是有道理的。但是,如果我從同一個班級的另一個對象訪問它並進行任何實施更改,我很清楚這些私人成員的更改和訪問,並可以採取相應措施。

另一件事想:

如果B類擴展類A,則任何B-對象也是一個A-對象,但它不能訪問私有A-方法。爲什麼如果私人方法是對象私有?

相關問題