Quel est le spécificateur d'accès par défaut en Java?

108

Je viens de commencer à lire un livre sur Java et je me suis demandé; quel spécificateur d'accès est celui par défaut, si aucun n'est spécifié?

Bennedich
la source
Le terme correct est «modificateur d'accès». Le mot «spécificateur» n'apparaît pas dans le JLS.
Marquis of Lorne

Réponses:

116

La visibilité par défaut est connue sous le nom de «package-private» (bien que vous ne puissiez pas l'utiliser explicitement), ce qui signifie que le champ sera accessible depuis l'intérieur du même package auquel appartient la classe.

Comme mdma l'a souligné, ce n'est pas vrai pour les membres de l'interface, pour lesquels la valeur par défaut est "public".

Voir les spécificateurs d'accès de Java

KeatsPeeks
la source
25
incorrect - pas vrai pour les membres de l'interface. l'accès par défaut est alors public
mdma
2
Il est en fait connu sous le nom de «package privé». Les sites Web tiers ne sont pas des références normatives. Vous ne devriez citer que le JLS.
Marquis of Lorne
81

Le spécificateur par défaut dépend du contexte.

Pour les classes et les déclarations d'interface, la valeur par défaut est package private. Cela se situe entre protégé et privé, autorisant uniquement les classes dans le même package d'accès. (protected est comme ça, mais permet également d'accéder à des sous-classes en dehors du paquet.)

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

   void calc() {  // package private method

   }
}

Pour les membres de l'interface (champs et méthodes), l'accès par défaut est public. Mais notez que la déclaration d'interface elle-même par défaut est package private.

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

   void method1();     // public abstract
}

Si nous avons alors la déclaration

public interface MyInterface2 extends MyInterface
{

}

Les classes utilisant MyInterface2 peuvent alors voir field1 et method1 depuis la super interface, car elles sont publiques, même si elles ne peuvent pas voir la déclaration de MyInterface elle-même.

mdma
la source
1
"Package private" (parfois écrit dans les sources comme /* pp */) n'est qu'un nom pratique pour l' accès par défaut . Ce n'est pas le nom JLS.
Tom Hawtin - tackline
10
@Tom - c'est correct, le JLS utilise "l'accès par défaut". J'aurais pu écrire "la valeur par défaut est l'accès par défaut". Mais cela n'a pas semblé très utile!
mdma
16

Si aucun spécificateur d'accès n'est donné, il s'agit d'un accès au niveau du package (il n'y a pas de spécificateur explicite pour cela) pour les classes et les membres de classe. Les méthodes d'interface sont implicitement publiques.

Michael Borgwardt
la source
9

La visibilité par défaut (pas de mot-clé) est package, ce qui signifie qu'elle sera disponible pour chaque classe qui se trouve dans le même package.

Une note latérale intéressante est que protected ne limite pas la visibilité aux sous-classes mais aussi aux autres classes du même package

Johannes Wachter
la source
8

Cela dépend de ce que c'est.

  • Les types de niveau supérieur (c'est-à-dire les classes, les énumérations, les interfaces et les types d'annotations non déclarés dans un autre type) sont privés par défaut. ( JLS §6.6.1 )

  • Dans les classes, tous les membres (c'est-à-dire les champs, les méthodes et les déclarations de types imbriqués) et les constructeurs sont privés par défaut. ( JLS §6.6.1 )

    • Lorsqu'une classe n'a pas de constructeur explicitement déclaré, le compilateur insère un constructeur à argument nul par défaut qui a le même spécificateur d'accès que la classe . ( JLS §8.8.9 ) Le constructeur par défaut est généralement erroné comme étant toujours public, mais dans de rares cas, ce n'est pas équivalent.
  • Dans les énumérations, les constructeurs sont privés par défaut. En effet, les constructeurs d'énumérations doivent être privés, et c'est une erreur de les spécifier comme publics ou protégés. Les constantes Enum sont toujours publiques et n'autorisent aucun spécificateur d'accès. Les autres membres d'énumérations sont privés de package par défaut. ( JLS §8.9 )

  • Dans les interfaces et les types d'annotations, tous les membres (encore une fois, cela signifie que les champs, les méthodes et les déclarations de types imbriqués) sont publics par défaut. En effet, les membres des interfaces et des types d'annotations doivent être publics, et c'est une erreur de les spécifier comme privés ou protégés. ( JLS §9.3 à 9.5 )

  • Les classes locales sont des classes nommées déclarées dans une méthode, un constructeur ou un bloc d'initialisation. Ils sont étendus au bloc {.. }dans lequel ils sont déclarés et n'autorisent aucun spécificateur d'accès. ( JLS §14.3 ) En utilisant la réflexion, vous pouvez instancier des classes locales ailleurs, et elles sont privées de package , bien que je ne sois pas sûr que ce détail se trouve dans le JLS.

  • Les classes anonymes sont des classes personnalisées créées avec newlesquelles spécifient un corps de classe directement dans l'expression. ( JLS §15.9.5 ) Leur syntaxe n'autorise aucun spécificateur d'accès. En utilisant la réflexion, vous pouvez instancier des classes anonymes d'ailleurs, et elles et leurs constructeurs générés sont privés de package , bien que je ne sois pas sûr que ce détail se trouve dans le JLS.

  • Les blocs d'initialisation d'instance et statique n'ont pas de spécificateurs d'accès au niveau du langage ( JLS §8.6 & 8.7 ), mais les blocs d'initialisation statiques sont implémentés comme une méthode nommée <clinit>( JVMS §2.9 ), donc la méthode doit, en interne, avoir un spécificateur d'accès. J'ai examiné les classes compilées par javac et par le compilateur d'Eclipse à l'aide d'un éditeur hexadécimal et j'ai trouvé que les deux génèrent la méthode en tant que package-private . Cependant, vous ne pouvez pas appeler <clinit>()dans la langue car les caractères <et ne >sont pas valides dans un nom de méthode et les méthodes de réflexion sont câblées pour nier son existence, de sorte que son spécificateur d'accès n'est pas un accès . La méthode ne peut être appelée que par la VM, lors de l'initialisation de la classe.Les blocs d'initialisation d' instance ne sont pas compilés en tant que méthodes distinctes; leur code est copié dans chaque constructeur, de sorte qu'ils ne sont pas accessibles individuellement, même par réflexion.

Boann
la source
7

default est un mot-clé utilisé comme modificateur d'accès pour les méthodes et les variables.
L'utilisation de ce modificateur d'accès rendra votre classe, variable, méthode ou constructeur accessible à partir de votre propre classe ou package, il sera également défini si aucun modificateur d'accès n'est présent.

  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

si vous utilisez un défaut dans une interface vous pourrez y implémenter une méthode comme cet exemple

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

Cependant, cela ne fonctionnera qu'à partir de la version 8 Java

Documentation officielle

Accéder aux modificateurs en Java

Amadeu Antunes
la source
3

Voir ici pour plus de détails. La valeur par défaut n'est pas privée / publique / protégée, mais une spécification d'accès complètement différente. Ce n'est pas très utilisé et je préfère être beaucoup plus précis dans mes définitions d'accès.

Brian Agnew
la source
3

le spécificateur d'accès par défaut est package. Les classes peuvent accéder aux membres d'autres classes dans le même package, mais en dehors du package, il apparaît comme privé

abhi
la source
3

Voici une citation sur la visibilité au niveau du package tirée d'une interview avec James Gosling, le créateur de Java:

Bill Venners : Java a quatre niveaux d'accès. La valeur par défaut est package. Je me suis toujours demandé si rendre l'accès aux packages par défaut était pratique car les trois mots-clés que les gens de C ++ connaissaient déjà étaient privés, protégés et publics. Ou si vous aviez une raison particulière pour laquelle vous estimiez que l'accès aux packages devrait être la valeur par défaut.

James Gosling : Un package est généralement un ensemble de choses qui sont en quelque sorte écrites ensemble. Donc, de manière générique, j'aurais pu faire l'une des deux choses. L'un était de vous forcer à toujours mettre un mot-clé qui vous donne le domaine. Ou j'aurais pu avoir une valeur par défaut. Et puis la question est, qu'est-ce qui fait un défaut raisonnable? Et j'ai tendance à opter pour ce qui est le moins dangereux.

Donc, public aurait été une très mauvaise chose pour faire le défaut. Private aurait probablement été une mauvaise chose à faire par défaut, ne serait-ce que parce que les gens n'écrivent pas souvent des méthodes privées. Et même chose avec protégé. Et en regardant un tas de code que j'avais, j'ai décidé que la chose la plus courante qui était raisonnablement sûre était dans le paquet. Et C ++ n'avait pas de mot clé pour cela, car ils n'avaient pas de notion de paquet.

Mais j'ai aimé plutôt que la notion d'amis, car avec des amis, vous devez en quelque sorte énumérer qui sont tous vos amis, et donc si vous ajoutez une nouvelle classe à un package, vous finissez généralement par devoir aller à tous les classes dans ce package et mettre à jour leurs amis, ce que j'avais toujours trouvé être une douleur totale dans le cul.

Mais la liste d'amis elle-même pose une sorte de problème de version. Et il y avait donc cette notion de classe amicale. Et la bonne chose que je faisais que ce soit la valeur par défaut - je vais résoudre le problème alors quel devrait être le mot-clé?

Pendant un certain temps, il y avait en fait un mot-clé convivial. Mais parce que tous les autres commencent par "P", c'était "phriendly" avec un "PH". Mais ce n'était là que pour peut-être un jour.

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

Vitalii Fedorenko
la source
2

Mettre à jour l' utilisation du defaultmot - clé Java 8 : comme beaucoup d'autres l'ont noté La visibilité par défaut (pas de mot-clé)

le champ sera accessible depuis l'intérieur du même package auquel appartient la classe.

À ne pas confondre avec la nouvelle fonctionnalité Java 8 ( méthodes par défaut ) qui permet à une interface de fournir une implémentation lorsqu'elle est étiquetée avec le defaultmot - clé.

Voir: Accéder aux modificateurs

Ahmad Sanie
la source
-2

Tout d'abord, permettez-moi de dire une chose qu'il n'y a pas de terme tel que "spécificateur d'accès" en java. Nous devrions tout appeler des "modificateurs". Comme nous savons que final, static, synchronized, volatile .... sont appelés comme modificateurs, même Public, private, protected, default, abstract devrait aussi être appelé comme modifiers. La valeur par défaut est un tel modificateur où l'existence physique n'est pas là mais aucun modificateur n'est placé, alors il doit être traité comme modificateur par défaut.

Pour justifier cela, prenons un exemple:

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

La sortie sera: Hello Java

Maintenant, changez public en privé et voyez quelle erreur du compilateur vous obtenez: Il dit "Le modificateur privé n'est pas autorisé ici" Quelle conclusion est que quelqu'un peut se tromper ou qu'un didacticiel peut être faux mais le compilateur ne peut pas se tromper. Nous pouvons donc dire qu'il n'y a pas de spécificateur d'accès aux termes en java, tout est des modificateurs.

Sagar Raut
la source
La première phrase est juste, mais le fait qu'une classe externe ne puisse pas être privée ne prouve pas qu'il n'existe pas de spécificateur d'accès en Java.
Marquis of Lorne
@EJP Ceci n'est qu'un exemple. Ce que je dis, c'est que le terme spécificateur d'accès est utilisé dans d'autres langages comme c, dot net, etc., mais le terme technique en java pour cela est des modificateurs. Si vous utilisez eclipse ou tout autre IDE, vous pouvez voir qu'au moment de la création d'une nouvelle classe, il nous est demandé de fournir le nom des modificateurs et dans la liste, ils fournissent public, privé, abstrait, etc.
Sagar Raut
Dans mon exemple, ce que j'essaie de dire que le compilateur donne un message d'erreur: les modificateurs privés ne sont pas autorisés, ils ne donnent pas de message comme le spécificateur d'accès privé non autorisé. Donc, le terme technique que nous devrions dire est que les modificateurs en java n'accèdent pas au spécificateur en java
Sagar Raut