Ich habe gerade angefangen, ein Java-Buch zu lesen und mich gefragt; Welcher Zugriffsspezifizierer ist der Standardspezifizierer, wenn keiner angegeben ist?
Ich habe gerade angefangen, ein Java-Buch zu lesen und mich gefragt; Welcher Zugriffsspezifizierer ist der Standardspezifizierer, wenn keiner angegeben ist?
Antworten:
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.
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.
/* pp */
) ist nur ein geeigneter Name für den Standardzugriff . Es ist nicht der JLS-Name.
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.
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
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 )
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 new
denen 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.
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
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.
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.
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
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:
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.