9 votes

une classe interne statique et un membre statique d'une classe partagent le même nom ?

Comment la classe interne statique M et le membre statique M [de la classe C partagent le même nom ?

Le code suivant génère "White" en sortie :

public class Amazed{

    public static void main(String[] args) {
        System.out.println(B.M.W);
    }
}

class B {
    public static class M {       
        static String W = "Black";
    }

    static C M = new C();
}

class C {
    String W = "White";
}

la façon dont on accède à l'objet membre et non au membre statique de la classe : W ["Black"]

Si je veux accéder à un membre d'une classe statique, comment faire ?

2voto

Ted Hopp Points 122617

Chapitre 6 de la spécification du langage Java (notamment Section 6.5 ) explique en détail comment Java détermine la signification d'un identifiant particulier dans un contexte particulier. Les règles sont assez complexes, mais, grosso modo, Java dispose de six espaces de noms :

  • Noms des paquets
  • noms des types
  • noms des champs (variables)
  • noms des méthodes
  • les noms des variables locales (y compris les paramètres)
  • étiquettes

Le même identifiant peut être utilisé pour des entités dans chacun de ces espaces de noms. Notez que les noms de types (classes) et les noms de champs vivent séparément, ce qui explique pourquoi votre code est légal.

Les noms hérités dans le même espace de noms peuvent aussi parfois être ombrés ou masqués. Il arrive qu'un identificateur soit ambigu ; il doit alors être qualifié d'une manière ou d'une autre (par exemple, avec un nom de paquetage), faute de quoi le compilateur se plaindra.

Les obscurcisseurs de code utilisent cela à bon escient, au point que l'on peut se retrouver avec un paquetage nommé a.a et une classe nommée a dans le paquet a (qui serait également identifié comme a.a ). Sans oublier que les mots clés de Java tels que do y for sont des noms légaux dans les fichiers .class (mais pas dans le code source Java). Cela fait de la rétro-ingénierie un véritable casse-tête.

1voto

Andy Thomas Points 30979

La variable masque le type du même nom. Si un nom peut être interprété comme étant soit une variable, soit un type, la variable est préférée.

Vous pouvez éviter cela en ne leur donnant pas le même nom.

Extrait de la spécification du langage Java, section 6.4.2 : Obscurcissement :

6.4.2. Obscurcissement

Un simple nom peut apparaître dans des contextes où il peut potentiellement être interprété comme le nom d'une variable, d'un type ou d'un paquetage. Dans ces situations, les règles du §6.5 précisent qu'une variable sera choisie de préférence à un type, et qu'un type sera choisi de préférence à un paquetage. Ainsi, il est parfois impossible de se référer à une déclaration de type ou de paquetage visible par son simple nom. Nous disons qu'une telle déclaration est obscure.

0voto

cyon Points 4365

Dans votre cas particulier où M peut être instancié, vous pouvez utiliser le fait que les éléments statiques peuvent être accédés de manière non statique :

public class Amazed{
   @SuppressWarnings("static-access")
   public static void main(String[] args) {
       B.M val = new B.M();
       System.out.println(val.W);
   }
}

class B {
   public static class M {       
       static String W = "Black";
   }

   static C M = new C();
}

class C {
   String W = "White";
}

L'exemple ci-dessus affichera "Noir" parce que vous avez désambiguïsé l'identifiant en y faisant référence par le biais d'une instance de B.M . Bien entendu, il ne s'agit en aucun cas d'une bonne idée dans un code de production, puisque les champs statiques ne doivent pas être accédés de manière non statique. De même, cela vous oblige à créer une instance de B.M .

0voto

Dineshkumar Points 3887

Après l'aide de tout le monde et un petit jeu, j'ai découvert que même sans créer d'objet pour la classe interne, nous pouvons accéder au membre W "Black".

en utilisant simplement cette déclaration

M.W

Mais je n'arrive pas à déterminer le niveau d'accès. [parce que c'est public ?] même sans public ça marche. comment ça se fait ?

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X