Was ist der Standardzugriffsspezifizierer in Java?

108

Ich habe gerade angefangen, ein Java-Buch zu lesen und mich gefragt; Welcher Zugriffsspezifizierer ist der Standardspezifizierer, wenn keiner angegeben ist?

bennedich
quelle
Der korrekte Begriff lautet "Zugriffsmodifikator". Das Wort "Spezifizierer" wird im JLS nicht angezeigt.
Marquis von Lorne

Antworten:

116

Die Standardsichtbarkeit wird als "package-private" bezeichnet (obwohl Sie dies nicht explizit verwenden können). Dies bedeutet, dass auf das Feld innerhalb desselben Pakets zugegriffen werden kann, zu dem die Klasse gehört.

Wie mdma betonte, gilt dies jedoch nicht für Schnittstellenmitglieder, für die der Standardwert "öffentlich" ist.

Siehe Javas Zugriffsspezifizierer

KeatsPeeks
quelle
25
falsch - nicht wahr für Schnittstellenmitglieder. Der Standardzugriff ist dann öffentlich
mdma
2
Es ist eigentlich als "Paket privat" bekannt. Websites von Drittanbietern sind keine normativen Referenzen. Sie sollten nur das JLS zitieren.
Marquis von Lorne
81

Der Standardbezeichner hängt vom Kontext ab.

Für Klassen und Schnittstellendeklarationen lautet der Standardwert package private. Dies liegt zwischen geschützt und privat und erlaubt nur Klassen im selben Paketzugriff. (protected ist wie folgt, ermöglicht aber auch den Zugriff auf Unterklassen außerhalb des Pakets.)

class MyClass   // package private
{
   int field;    // package private field

   void calc() {  // package private method

   }
}

Für Schnittstellenmitglieder (Felder und Methoden) ist der Standardzugriff öffentlich. Beachten Sie jedoch, dass die Schnittstellendeklaration selbst standardmäßig das Paket private ist.

interface MyInterface  // package private
{
   int field1;         // static final public

   void method1();     // public abstract
}

Wenn wir dann die Erklärung haben

public interface MyInterface2 extends MyInterface
{

}

Klassen, die MyInterface2 verwenden, können dann Feld1 und Methode1 über die Superschnittstelle anzeigen, da sie öffentlich sind, obwohl sie die Deklaration von MyInterface selbst nicht sehen können.

mdma
quelle
1
"Paket privat" (manchmal in der Quelle geschrieben als /* pp */) ist nur ein geeigneter Name für den Standardzugriff . Es ist nicht der JLS-Name.
Tom Hawtin - Tackline
10
@ Tom - das ist richtig, der JLS verwendet "Standardzugriff". Ich hätte schreiben können "der Standard ist Standardzugriff". Aber das schien nicht allzu hilfreich zu sein!
Mdma
16

Wenn kein Zugriffsspezifizierer angegeben ist, erfolgt der Zugriff auf Paketebene (es gibt keinen expliziten Spezifizierer dafür) für Klassen und Klassenmitglieder. Schnittstellenmethoden sind implizit öffentlich.

Michael Borgwardt
quelle
9

Die Standardsichtbarkeit (kein Schlüsselwort) ist package. Dies bedeutet, dass es für jede Klasse verfügbar ist, die sich im selben Paket befindet.

Interessant ist, dass protected die Sichtbarkeit nicht auf die Unterklassen beschränkt, sondern auch auf die anderen Klassen im selben Paket

Johannes Wachter
quelle
8

Es kommt darauf an, was das Ding ist.

  • Top-Level - Typen (dh Klassen, Aufzählungen, Schnittstellen und Annotationstypen nicht innerhalb eines anderen Typs deklariert) sind Paket-private standardmäßig. ( JLS §6.6.1 )

  • In den Klassen, alle Mitglieder (dh Felder, Methoden und verschachtelte Typdeklarationen) und Konstrukteure sind Paket-private standardmäßig. ( JLS §6.6.1 )

    • Wenn eine Klasse keinen explizit deklarierten Konstruktor hat, fügt der Compiler einen Standardkonstruktor mit null Argumenten ein, der denselben Zugriffsspezifizierer wie die Klasse hat . ( JLS §8.8.9 ) Der Standardkonstruktor wird häufig falsch angegeben, da er immer öffentlich ist. In seltenen Fällen ist dies jedoch nicht gleichwertig.
  • In Aufzählungen sind Konstruktoren standardmäßig privat . Tatsächlich Enum contructors muss privat sein, und es ist ein Fehler , sie als öffentlich zu spezifizieren oder geschützt. Enum-Konstanten sind immer öffentlich und erlauben keinen Zugriffsspezifizierer. Andere Mitglieder von Aufzählungen sind Paket-private standardmäßig. ( JLS §8.9 )

  • In Schnittstellen und Annotationstypen sind alle Elemente (wiederum Felder, Methoden und verschachtelte Typdeklarationen) standardmäßig öffentlich . Tatsächlich Mitglieder von Schnittstellen und Annotationstypen müssen öffentlich sein, und es ist ein Fehler , sie als privat zu spezifizieren oder geschützt. ( JLS §9.3 bis 9.5 )

  • Lokale Klassen sind benannte Klassen, die in einer Methode, einem Konstruktor oder einem Initialisierungsblock deklariert sind. Sie sind auf den Block {.. beschränkt }, in dem sie deklariert sind, und erlauben keinen Zugriffsspezifizierer. ( JLS §14.3 ) Reflexion verwenden, können Sie aus anderen lokalen Klassen instanziiert, und sie sind Paket-private , obwohl ich nicht sicher bin , ob das Detail in den JLS ist.

  • Anonyme Klassen sind benutzerdefinierte Klassen, mit newdenen ein Klassenkörper direkt im Ausdruck angegeben wird. ( JLS §15.9.5 ) Ihre Syntax erlaubt keinen Zugriffsspezifizierer. Mithilfe von Reflection können Sie anonyme Klassen von einer anderen Stelle aus instanziieren, und sowohl sie als auch ihre generierten Konstruktoren sind paketprivat , obwohl ich nicht sicher bin, ob dieses Detail im JLS enthalten ist.

  • Instanz- und statische Initialisierungsblöcke haben keine Zugriffsspezifizierer auf Sprachebene ( JLS §8.6 und 8.7 ), aber statische Initialisierungsblöcke werden als Methode mit dem Namen <clinit>( JVMS §2.9 ) implementiert , sodass die Methode intern über einen Zugriffsspezifizierer verfügen muss. Ich habe Klassen untersucht, die von javac und Eclipse mit einem Hex-Editor kompiliert wurden, und festgestellt, dass beide die Methode als package-private generieren . Sie können jedoch nicht <clinit>()innerhalb der Sprache aufrufen, da die Zeichen <und >in einem Methodennamen ungültig sind und die Reflektionsmethoden fest verdrahtet sind, um ihre Existenz zu leugnen. Daher ist dies effektiv der Zugriffsspezifizierer Zugriffsspezifizierer kein Zugriff . Die Methode kann nur von der VM während der Klasseninitialisierung aufgerufen werden.Instanzinitialisierungsblöcke werden nicht als separate Methoden kompiliert. Ihr Code wird in jeden Konstruktor kopiert, sodass auch durch Reflexion nicht einzeln auf sie zugegriffen werden kann.

Boann
quelle
7

Standard ist ein Schlüsselwort, das als Zugriffsmodifikator für Methoden und Variablen verwendet wird.
Die Verwendung dieses Zugriffsmodifikators macht Ihre Klasse, Variable, Methode oder Ihren Konstruktor von der eigenen Klasse oder dem eigenen Paket aus zugänglich. Er wird auch festgelegt, wenn kein Zugriffsmodifikator vorhanden ist.

  Access Levels
    Modifier    Class   Package Subclass  EveryWhere
    public        Y        Y       Y         Y
    protected     Y        Y       Y         N
    default       Y        Y       N         N
    private       Y        N       N         N

Wenn Sie eine Standardeinstellung in einer Schnittstelle verwenden, können Sie dort eine Methode wie diese implementieren

public interface Computer {    
    default void Start() {
        throw new UnsupportedOperationException("Error");
    }    
}

Es funktioniert jedoch nur ab der 8 Java-Version

Offizielle Dokumentation

Zugriffsmodifikatoren in Java

Amadeu Antunes
quelle
3

Sehen Sie hier für weitere Details. Der Standardwert ist nicht privat / öffentlich / geschützt, sondern eine völlig andere Zugriffsspezifikation. Es ist nicht weit verbreitet und ich bevorzuge es, in meinen Zugriffsdefinitionen viel spezifischer zu sein.

Brian Agnew
quelle
3

Der Standardzugriffsspezifizierer ist package. Klassen können auf die Mitglieder anderer Klassen im selben Paket zugreifen. Außerhalb des Pakets wird es jedoch als privat angezeigt

abhi
quelle
3

Hier ist ein Zitat über die Sichtbarkeit auf Paketebene aus einem Interview mit James Gosling, dem Erfinder von Java:

Bill Venners : Java hat vier Zugriffsebenen. Der Standardwert ist package. Ich habe mich immer gefragt, ob es praktisch ist, den Paketzugriff als Standard festzulegen, da die drei Schlüsselwörter, die C ++ bereits kannte, privat, geschützt und öffentlich waren. Oder wenn Sie einen bestimmten Grund hatten, aus dem Sie der Meinung waren, dass der Paketzugriff die Standardeinstellung sein sollte.

James Gosling : Ein Paket besteht im Allgemeinen aus einer Reihe von Dingen, die zusammen geschrieben sind. Generisch hätte ich eines von zwei Dingen tun können. Eine davon war, dass Sie immer ein Schlüsselwort eingeben mussten, das Ihnen die Domain gibt. Oder ich hätte einen Standardwert haben können. Und dann ist die Frage, was macht einen vernünftigen Standard? Und ich neige dazu, das zu tun, was am wenigsten gefährlich ist.

Die Öffentlichkeit wäre also eine wirklich schlechte Sache gewesen, um den Standard festzulegen. Privat wäre wahrscheinlich eine schlechte Sache gewesen, um einen Standard festzulegen, schon allein deshalb, weil die Leute nicht so oft private Methoden schreiben. Und das Gleiche mit geschützt. Und als ich mir eine Menge Code ansah, die ich hatte, entschied ich, dass das Paket das häufigste war, was einigermaßen sicher war. Und C ++ hatte kein Schlüsselwort dafür, weil sie keine Vorstellung von Paketen hatten.

Aber ich mochte es eher als die Vorstellung von Freunden, denn bei Freunden muss man irgendwie aufzählen, wer alle Ihre Freunde sind. Wenn Sie also einem Paket eine neue Klasse hinzufügen, müssen Sie im Allgemeinen zu allen gehen Klassen in diesem Paket und aktualisieren ihre Freunde, was ich immer als ein völliger Schmerz im Hintern empfunden hatte.

Aber die Freundesliste selbst verursacht eine Art Versionsproblem. Und so gab es die Vorstellung einer freundlichen Klasse. Und das Schöne, dass ich das zum Standard gemacht habe - ich werde das Problem lösen. Wie sollte das Schlüsselwort lauten?

Für eine Weile gab es tatsächlich ein freundliches Schlüsselwort. Aber weil alle anderen mit "P" beginnen, war es "phriendly" mit einem "PH". Aber das war vielleicht nur einen Tag lang da.

http://www.artima.com/intv/gosling2P.html

Vitalii Fedorenko
quelle
2

Aktualisieren Sie die Verwendung des Schlüsselworts in Java 8default : Wie viele andere angemerkt haben Die Standardsichtbarkeit (kein Schlüsselwort)

Auf das Feld kann von demselben Paket aus zugegriffen werden, zu dem die Klasse gehört.

Nicht zu verwechseln mit der neuen Java 8- Funktion ( Standardmethoden ), mit der eine Schnittstelle eine Implementierung bereitstellen kann, wenn sie mit dem gekennzeichnet istdefault Schlüsselwort gekennzeichnet ist.

Siehe: Zugriffsmodifikatoren

Ahmad Sanie
quelle
1

In JAVA gibt es einen Zugriffsmodifikator namens "default", der die direkte Instanzerstellung dieser Entität nur innerhalb dieses Pakets ermöglicht.

Hier ist ein nützlicher Link:

Java Access Modifiers / Specifiers

Krishna Ganeriwal
quelle
-2

Lassen Sie mich zunächst einmal sagen, dass es in Java keinen Begriff wie "Zugriffsspezifizierer" gibt. Wir sollten alles als "Modifikatoren" bezeichnen. Da wir wissen, dass endgültige, statische, synchronisierte, flüchtige ... als Modifikatoren bezeichnet werden, sollten auch öffentliche, private, geschützte, standardmäßige, abstrakte als Modifikatoren bezeichnet werden. Standard sind solche Modifikatoren, bei denen keine physische Existenz vorhanden ist, aber keine Modifikatoren platziert sind. Dann sollten sie als Standardmodifikatoren behandelt werden.

Um dies zu rechtfertigen, nehmen Sie ein Beispiel:

public class Simple{  
    public static void main(String args[]){  
     System.out.println("Hello Java");  
    }  
}  

Ausgabe wird sein: Hello Java

Ändern Sie nun public in private und sehen Sie, welchen Compilerfehler Sie erhalten: Es heißt "Modifier private ist hier nicht zulässig". Die Schlussfolgerung lautet, dass jemand falsch sein kann oder dass ein Tutorial falsch sein kann, der Compiler jedoch nicht falsch sein kann. Wir können also sagen, dass es in Java keinen Begriff Zugriffsspezifizierer gibt. Alles sind Modifikatoren.

Sagar Raut
quelle
Der erste Satz ist genau richtig, aber die Tatsache, dass eine äußere Klasse nicht privat sein kann, beweist nicht, dass es in Java keinen Zugriffsspezifizierer gibt.
Marquis von Lorne
@EJP Dies ist nur ein Beispiel. Was ich sage ist, dass der Begriff Zugriffsspezifizierer in anderen Sprachen wie c, dot net usw. verwendet wird, aber der technische Begriff in Java dafür sind Modifikatoren. Wenn Sie Eclipse oder eine andere IDE verwenden, können Sie sehen, dass wir zum Zeitpunkt der Erstellung einer neuen Klasse aufgefordert werden, den Namen der Modifikatoren anzugeben und in der Liste öffentliche, private, abstrakte usw. anzugeben
Sagar Raut
In meinem Beispiel versuche ich zu sagen, dass der Compiler eine Fehlermeldung gibt: Modifikatoren privat sind nicht erlaubt, es gibt keine Nachricht wie Zugriffsspezifizierer privat nicht erlaubt. Der technische Begriff, den wir sagen sollten, ist also, dass Modifikatoren in Java nicht auf Spezifizierer in Java zugreifen
Sagar Raut