Java intérieure visibilité de classe puzzle
Considérons le cas suivant:
public class A {
public A() { b = new B(); }
B b;
private class B { }
}
D'un avertissement dans Eclipse, je cite, que: le compilateur java émule le constructeur de A. B() par un synthétique de la méthode d'accesseur. Je suppose que le compilateur va de l'avant et crée une "sous l'eau" constructeur de B.
J'ai l'impression que c'est plutôt étrange: pourquoi la classe B de ne pas être visible comme un.k.o. dans Un champ?
Et: est-ce que cela signifie que la classe B est plus privé au moment de l'exécution?
Et: pourquoi se comporte le mot clé protected de la classe B est différent?
public class A {
public A() { b = new B(); }
B b;
protected class B { }
}
OriginalL'auteur Gerard | 2009-07-06
Vous devez vous connecter pour publier un commentaire.
Les classes internes sont essentiellement un hack introduit dans Java 1.1. La JVM n'est pas réellement le concept de l'un à l'intérieur de la classe, et donc que le compilateur doit bodge. Le compilateur génère de classe B "à l'extérieur" de la classe A, mais dans le même package, puis ajoute synthétique accesseurs/constructeurs pour permettre Un pour obtenir l'accès.
Quand vous donnez B a protégé constructeur, Un peut accéder à ce constructeur, puisque c'est dans le même paquet, sans avoir besoin d'un synthétique constructeur à être ajouté.
Je ne vous en faites pas. Ce message d'avertissement du compilateur n'est pas vraiment une grande utilité pour toute personne, de méthodes synthétiques sont utilisés tout le temps à l'intérieur des classes, et n'ont pas d'impact significatif.
À mon humble avis, les méthodes de synthèse ont été inutilement plus de la langue. Juste à l'aide de l'étendue d'un package pour le "privé" membres (dont le compilateur n'sous le capot de toute façon) était une solution satisfaisante.
mais les membres sont toujours en "privé" pour les autres classes dans le package...
Je pense que ce n'est pas la "vérité", voir la répondre je viens de poster...
OriginalL'auteur skaffman
Je sais que cette question est maintenant presque trois ans, mais je trouve qu'une partie de la question est toujours pas de réponse:
Carlos Heubergers commentaire sur skaffmans répondre à l'indique, la classe
B
est encoreprivate
pour les autres classes dans le package.Il est probablement vrai pour le langage de programmation Java, c'est à dire qu'il n'est pas possible de se référer à la classe
B
à partir d'une autre classe. Du moins pas sans l'aide de réflexion (qui a également privé les membres de la classe peuvent être accessibles depuis l'extérieur), mais c'est une autre question.Mais comme la JVM n'a pas de concept de l'un à l'intérieur de la classe (comme skaffman unis), je me suis demandé comment un "accessible que par une seule classe" la visibilité est réalisé au niveau du bytecode. La réponse: Il n'est pas réalisé du tout, pour la JVM de l'intérieur de la classe ressemble à un paquet de classe privée. C'est, si vous écrivez un bytecode pour vous-même (ou de modifier celui généré par le compilateur), vous pouvez accéder à la classe
B
sans problèmes.Vous pouvez accéder à tous les synthétiques méthodes d'accès de toutes les classes du même package. Donc, si vous affectez une valeur à un champ privé de la classe
A
dans une méthode de classeB
, un synthétique de la méthode d'accesseur par défaut (c'est à dire colis privé) la visibilité est généré dans la classeA
(nommé quelque chose commeaccess$000
) qui définit la valeur pour vous. Cette méthode est censée être appelé de la classeB
(et en effet il ne peut être appelé à partir de là, en utilisant le langage Java). Mais à partir de la Jvm point de vue, c'est juste une méthode que les autres et peut être appelée par n'importe quelle classe.Donc, pour répondre à la question:
B
est et reste privé.B
(ou mieux: de la classeA$B
) n'est pas privé.bien sûr, ce n'était pas une offense à vous! Certainement les membres de la classe B sont encore privés, mais ceux de la classe B (comme une sorte de membre de la catégorie A) n'est pas (à partir de la Jvm point de vue), et c'était la question de départ, par Gérard. Et oui, la question est de savoir sur java, mais comme indiqué dans la balise wiki: "Java est un langage de programmation et environnement d'exécution". Et de l'environnement d'exécution est la JVM et la JVM en soi n'a rien à voir avec le langage de programmation Java, mais seulement interprète le bytecode.
OriginalL'auteur siegi
L'accès des
class B
et de son constructeur n'ont pas à être les mêmes. Vous pouvez avoir un privé intérieur de la classe avec un paquet-portée constructeur, et c'est ce que je fais d'habitude.OriginalL'auteur finnw
Vous devez utiliser
que ne fera aucune différence pour le problème en main. "Cette" qualification " est implicite.
OriginalL'auteur Ratnesh Maurya