Qual è l'identificatore di accesso predefinito in Java?


108

Ho appena iniziato a leggere un libro su Java e mi sono chiesto; quale specificatore di accesso è quello predefinito, se nessuno è specificato?


Il termine corretto è "modificatore di accesso". La parola "specificatore" non compare nel JLS.
Marchese di Lorne

Risposte:


116

La visibilità predefinita è nota come "pacchetto-privato" (sebbene non sia possibile utilizzarla esplicitamente), il che significa che il campo sarà accessibile dall'interno dello stesso pacchetto a cui appartiene la classe.

Come ha sottolineato mdma, non è vero per i membri dell'interfaccia, per i quali l'impostazione predefinita è "public".

Vedere gli specificatori di accesso di Java


25
errato - non vero per i membri dell'interfaccia. l'accesso predefinito è quindi pubblico
mdma

2
In realtà è noto come "pacchetto privato". I siti web di terze parti non sono riferimenti normativi. Dovresti citare solo il JLS.
Marchese di Lorne

81

Lo specificatore predefinito dipende dal contesto.

Per le classi e le dichiarazioni di interfaccia, il valore predefinito è pacchetto privato. Questo rientra tra protetto e privato, consentendo l'accesso solo alle classi nello stesso pacchetto. (protetto è così, ma consente anche l'accesso a sottoclassi al di fuori del pacchetto.)

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

   void calc() {  // package private method

   }
}

Per i membri dell'interfaccia (campi e metodi), l'accesso predefinito è pubblico. Ma si noti che la dichiarazione dell'interfaccia stessa ha come impostazione predefinita il pacchetto privato.

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

   void method1();     // public abstract
}

Se poi abbiamo la dichiarazione

public interface MyInterface2 extends MyInterface
{

}

Le classi che utilizzano MyInterface2 possono quindi vedere field1 e method1 dalla super interfaccia, perché sono pubbliche, anche se non possono vedere la dichiarazione di MyInterface stessa.


1
"Pacchetto privato" (a volte scritto nel codice sorgente come /* pp */) è solo un nome conveniente per l' accesso predefinito . Non è il nome JLS.
Tom Hawtin - tackline

10
@ Tom - è corretto, il JLS utilizza "accesso predefinito". Avrei potuto scrivere "l'impostazione predefinita è l'accesso predefinito". Ma non mi è sembrato molto utile!
mdma

16

Se non viene fornito alcun identificatore di accesso, si tratta di un accesso a livello di pacchetto (non esiste uno specificatore esplicito per questo) per classi e membri di classe. I metodi di interfaccia sono implicitamente pubblici.


9

La visibilità predefinita (nessuna parola chiave) è pacchetto, il che significa che sarà disponibile per ogni classe che si trova nello stesso pacchetto.

Una nota a margine interessante è che protected non limita la visibilità alle sottoclassi ma anche alle altre classi nello stesso pacchetto


8

Dipende da cosa è la cosa.

  • I tipi di primo livello (ovvero classi, enumerazioni, interfacce e tipi di annotazione non dichiarati all'interno di un altro tipo) sono privati ​​del pacchetto per impostazione predefinita. ( JLS §6.6.1 )

  • Nelle classi, tutti i membri (che significa campi, metodi e dichiarazioni di tipi annidati) e costruttori sono privati ​​del pacchetto per impostazione predefinita. ( JLS §6.6.1 )

    • Quando una classe non ha un costruttore dichiarato esplicitamente, il compilatore inserisce un costruttore predefinito con zero argomenti che ha lo stesso identificatore di accesso della classe . ( JLS §8.8.9 ) Il costruttore predefinito è comunemente dichiarato erroneamente come sempre pubblico, ma in rari casi non è equivalente.
  • Nelle enumerazioni, i costruttori sono privati per impostazione predefinita. In effetti, i costruttori di enum devono essere privati ​​ed è un errore specificarli come pubblici o protetti. Le costanti Enum sono sempre pubbliche e non consentono alcun identificatore di accesso. Gli altri membri di enumerazioni sono privati ​​del pacchetto per impostazione predefinita. ( JLS §8.9 )

  • Nelle interfacce e nei tipi di annotazione, tutti i membri (di nuovo, ciò significa che i campi, i metodi e le dichiarazioni di tipo annidato) sono pubblici per impostazione predefinita. In effetti, i membri delle interfacce e dei tipi di annotazione devono essere pubblici ed è un errore specificarli come privati ​​o protetti. ( JLS §9.3-9.5 )

  • Le classi locali sono classi denominate dichiarate all'interno di un metodo, un costruttore o un blocco di inizializzazione. Hanno l' ambito del blocco {.. }in cui sono dichiarati e non consentono alcun identificatore di accesso. ( JLS §14.3 ) Usando la reflection, puoi istanziare classi locali da altrove, e sono private del pacchetto , anche se non sono sicuro che quel dettaglio sia nel JLS.

  • Le classi anonime sono classi personalizzate create con le newquali specificare il corpo di una classe direttamente nell'espressione. ( JLS §15.9.5 ) La loro sintassi non consente alcun identificatore di accesso. Usando la reflection, puoi istanziare classi anonime da altrove, e sia loro che i loro costruttori generati sono privati ​​del pacchetto , anche se non sono sicuro che quel dettaglio sia nel JLS.

  • I blocchi di istanza e inizializzatori statici non hanno specificatori di accesso a livello di linguaggio ( JLS §8.6 e 8.7 ), ma i blocchi di inizializzatori statici sono implementati come un metodo denominato <clinit>( JVMS §2.9 ), quindi il metodo deve, internamente, avere alcuni specificatori di accesso. Ho esaminato le classi compilate da javac e dal compilatore di Eclipse utilizzando un editor esadecimale e ho scoperto che entrambi generano il metodo come pacchetto privato . Tuttavia, non è possibile chiamare <clinit>()all'interno della lingua perché i caratteri <e >non sono validi nel nome di un metodo ei metodi di riflessione sono cablati per negare la sua esistenza, quindi il suo specificatore di accesso è nessun accesso . Il metodo può essere chiamato solo dalla VM, durante l'inizializzazione della classe.I blocchi di inizializzazione delle istanze non vengono compilati come metodi separati; il loro codice viene copiato in ogni costruttore, quindi non è possibile accedervi individualmente, nemmeno per riflessione.


7

default è una parola chiave utilizzata come modificatore di accesso per metodi e variabili.
L'uso di questo modificatore di accesso renderà la tua classe, variabile, metodo o costruttore accessibile dalla propria classe o pacchetto, sarà anche impostato se non è presente alcun modificatore di accesso.

  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

se usi un valore predefinito in un'interfaccia sarai in grado di implementare un metodo come questo esempio

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

Tuttavia funzionerà solo dalla versione 8 Java

Documentazione ufficiale

Modificatori di accesso in Java


3

Vedi qui per maggiori dettagli. L'impostazione predefinita non è privato / pubblico / protetto, ma una specifica di accesso completamente diversa. Non è ampiamente utilizzato e preferisco essere molto più specifico nelle mie definizioni di accesso.


3

lo specificatore di accesso predefinito è pacchetto. Le classi possono accedere ai membri di altre classi nello stesso pacchetto, ma al di fuori del pacchetto appare come privato


3

Ecco una citazione sulla visibilità a livello di pacchetto da un'intervista con James Gosling, il creatore di Java:

Bill Venners : Java ha quattro livelli di accesso. L'impostazione predefinita è package. Mi sono sempre chiesto se rendere l'accesso ai pacchetti predefinito fosse conveniente perché le tre parole chiave che le persone di C ++ già conoscevano erano private, protette e pubbliche. O se hai qualche motivo particolare per cui ritieni che l'accesso ai pacchetti debba essere l'impostazione predefinita.

James Gosling : Un pacchetto è generalmente un insieme di cose che vengono scritte insieme. Quindi genericamente avrei potuto fare una delle due cose. Uno era costringerti a inserire sempre una parola chiave che ti dia il dominio. Oppure avrei potuto avere un valore predefinito. E poi la domanda è: cosa rende ragionevole un default? E tendo a scegliere ciò che è la cosa meno pericolosa.

Quindi pubblico sarebbe stato davvero una brutta cosa per rendere l'impostazione predefinita. Privato sarebbe stato probabilmente una brutta cosa da impostare come predefinito, se non altro perché le persone in realtà non scrivono metodi privati ​​così spesso. E la stessa cosa con protected. E guardando un mucchio di codice che avevo, ho deciso che la cosa più comune che era ragionevolmente sicura era nel pacchetto. E C ++ non aveva una parola chiave per questo, perché non avevano una nozione di pacchetti.

Ma mi è piaciuto piuttosto che il concetto di amici, perché con gli amici devi in ​​qualche modo enumerare chi sono tutti i tuoi amici, e quindi se aggiungi una nuova classe a un pacchetto, in genere finisci per dover andare a tutti i classi in quel pacchetto e aggiornare i loro amici, che avevo sempre trovato essere un completo rompicoglioni.

Ma la stessa lista di amici causa una sorta di problema di controllo delle versioni. E quindi c'era questa nozione di una classe amichevole. E la cosa bella che stavo impostando come predefinita: risolverò il problema, quindi quale dovrebbe essere la parola chiave?

Per un po 'ci fu effettivamente una parola chiave amichevole. Ma poiché tutti gli altri iniziano con "P", era "amico" con "PH". Ma era lì solo per forse un giorno.

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


2

Aggiorna Java 8 utilizzo della defaultparola chiave: come molti altri hanno notato La visibilità predefinita (nessuna parola chiave)

il campo sarà accessibile dall'interno dello stesso pacchetto a cui appartiene la classe.

Da non confondere con la nuova funzionalità Java 8 ( metodi predefiniti ) che consente a un'interfaccia di fornire un'implementazione quando etichettata con la defaultparola chiave.

Vedi: Modificatori di accesso



-2

Prima di tutto lasciatemi dire una cosa che non esiste un termine come "specificatore di accesso" in java. Dovremmo chiamare tutto come "modificatori". Come sappiamo che finali, statici, sincronizzati, volatili .... sono chiamati come modificatori, anche Public, private, protected, default, abstract dovrebbero essere chiamati come modificatori. L'impostazione predefinita è un modificatore di questo tipo in cui l'esistenza fisica non è presente ma non viene inserito alcun modificatore, quindi dovrebbe essere trattato come modificatore predefinito.

Per giustificare questo, prendi un esempio:

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

L'output sarà: Hello Java

Ora cambia public in private e guarda quale errore del compilatore ottieni: dice "Il modificatore privato non è consentito qui" Quale conclusione è che qualcuno può sbagliarsi o qualche tutorial può essere sbagliato ma il compilatore non può sbagliare. Quindi possiamo dire che non esiste un identificatore di accesso al termine in java, tutto è modificatore.


La prima frase è azzeccata, ma il fatto che una classe esterna non possa essere privata non prova che non esista uno specificatore di accesso in Java.
Marchese di Lorne

@EJP Questo è solo un esempio. Quello che sto dicendo è che il termine identificatore di accesso è usato in altri linguaggi come c, dot net ecc, ma il termine tecnico in java per questo è modificatori. Se usi eclipse o qualsiasi altro IDE puoi vedere che al momento della creazione di una nuova classe ci viene chiesto di fornire il nome dei modificatori e nell'elenco forniscono pubblico, privato, astratto, ecc.
Sagar Raut

Nel mio esempio quello che cerco di dire che il compilatore fornisce un messaggio di errore: i modificatori privati ​​non sono consentiti, non fornisce messaggi come specificatore di accesso privato non consentito. Quindi il termine tecnico che dovremmo dire è modificatori in java non specificatore di accesso in java
Sagar Raut
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.