private

Kapunk fordítási hibát a kommentelt soroknál a Java fordítótól?

class A {
	private int a;
	
	class InnerA {
		private int b;
		
		void m2() {
			a = 9; // #1
		}
	}

	void m1() {
		InnerA innerA = new InnerA();
		innerA.b = 8; // #2
	}

}

Válasz hajtás után.

Nem, a fenti kód helyes, minden gond nélkül lefordul.

Számomra eddig az volt a private definíciója, hogy az adott osztályon belül látható, amúgy meg nem. A #1-gyel jelölt sor eszerint rendben van, hiszen az A osztály privát mezőjét az A osztályon belülről érjük el. (Igaz, egy alosztályból, de az is A-n belül van.) A #2-vel jelölt sornál viszont InnerA-n kívülről érjük el annak egy privát mezőjét, amire az előbbi definíció alapján nem lenne lehetőségünk.

Nem tudom, hogy ez a definíció még a C++-ból maradt-e meg a fejemben (bár már fogalmam sincs, ott ez hogyan működik), de a Java ezen tulajdonságát még sehol sem láttam direkt tudatosítva. Az SCJP könyvben sem találtam róla semmit, csak egy tesztkérdést, ami részben erre épül (3. fejezet, 7. tesztkérdés).

Kicsit utánanéztem a témának. A private-ről Java Language Specification 6.6.1-es pontja a következőket mondja:

„Otherwise, if the member or constructor is declared private, then access is permitted if and only if it occurs within the body of the top level class (§7.6) that encloses the declaration of the member or constructor.”

Tehát a privát mezők, metódusok, osztályok, interfészek a top level class-on belül mindenhonnan elérhetőek. A top level class definícióját a 8. fejezetben találjuk:

„A nested class is any class whose declaration occurs within the body of another class or interface. A top level class is a class that is not a nested class.”

Vagyis minden osztály beágyazott osztály, ami egy másik osztályon belül van deklarálva. Ami pedig nem beágyazott osztály, az top level class.

Rejtély megfejtve.

Tartalom átvétel