Risposte:
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".
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.
/* pp */
) è solo un nome conveniente per l' accesso predefinito . Non è il nome JLS.
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.
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
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 )
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 new
quali 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.
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
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.
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.
Aggiorna Java 8 utilizzo della default
parola 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 default
parola chiave.
Vedi: Modificatori di accesso
Esiste un modificatore di accesso chiamato "default" in JAVA, che consente la creazione diretta di istanze di quell'entità solo all'interno di quel pacchetto.
Ecco un link utile:
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.