java在类的内部创建本类的对象是怎么做到的?不理解啊?
ringa_lee
ringa_lee 2017-04-18 10:51:14
0
8
540

ringa_lee
ringa_lee

ringa_lee

répondre à tous(8)
黄舟

Tout d'abord, clarifiez quelques concepts. Le code Java s'exécute en jvm, et la zone mémoire de jvm est divisée en plusieurs modules :

  • Registre du compteur de programme : Le compteur de programme est une zone mémoire relativement petite utilisée pour indiquer quelle ligne de bytecode exécuté par le thread actuel a été exécutée. Il peut être compris comme étant le numéro de ligne. indicateur du fil de discussion actuel. Lorsque l'interpréteur de bytecode fonctionne, il récupérera une instruction d'instruction en modifiant la valeur de ce compteur.

  • Pile JVM : Lorsque chaque méthode d'un thread est exécutée, un cadre de pile (Statck Frame) sera créé et la table des variables locales est stockée dans le cadre de pile, station d'opération. , lien dynamique, sortie de méthode, etc. Lorsque la méthode est appelée, le cadre de pile est poussé dans la pile JVM. Lorsque l'exécution de la méthode est terminée, le cadre de pile est retiré de la pile.

  • Pile de méthodes natives : La pile de méthodes natives est la même que la pile de machines virtuelles en termes de fonction, de mécanisme d'exploitation, de types d'exceptions, etc. La seule différence est : la pile de machines virtuelles est Exécuter des méthodes Java, tandis que la pile de méthodes locales est utilisée pour exécuter des méthodes natives. Dans de nombreuses machines virtuelles (telles que la machine virtuelle HotSpot par défaut du JDK de Sun), la pile de méthodes locales et la pile de machines virtuelles sont utilisées ensemble.

  • Tas : La zone du tas est la zone la plus importante pour comprendre le mécanisme Java GC, sans exception. La zone de tas est la plus grande partie de mémoire gérée par la JVM. La zone de tas est également la zone de mémoire principale gérée par le mécanisme Java GC. La zone de tas est partagée par tous les threads et est créée au démarrage de la machine virtuelle. La zone de tas existe pour stocker les instances d'objets. En principe, tous les objets se voient allouer de la mémoire sur la zone de tas (mais dans la technologie moderne, ce n'est pas si absolu et certains objets sont alloués directement sur la pile).

  • Zone de méthode : (également connue sous le nom de génération permanente). La zone de méthode est une zone partagée par chaque thread et est utilisée pour stocker les informations de classe qui ont été chargées par la machine virtuelle ( c'est-à-dire les informations qui doivent être chargées lors du chargement d'une classe, y compris la version, le champ, la méthode, l'interface et d'autres informations), les constantes finales, les variables statiques, le code compilé par le compilateur à la volée, etc.

  • Mémoire directe : La mémoire directe n'est pas une mémoire gérée par la JVM. On peut comprendre que la mémoire directe est une mémoire machine autre que la JVM. Par exemple, si vous disposez de 4 Go de mémoire, la JVM. occupe 1G, et les 3G restants sont de la mémoire directe.Il existe une méthode d'allocation de mémoire basée sur le canal et le tampon dans JDK. La bibliothèque de fonctions native implémentée en langage C est allouée en mémoire directe et est stockée dans DirectByteBuffer dans le tas JVM pour référence. . La mémoire directe étant limitée par la mémoire de la machine, une exception OutOfMemoryError peut également se produire.

Après avoir compris ces concepts de base, examinons les domaines sur lesquels la personne qui pose la question a des doutes. En fait, ce que l'interrogateur se demande, c'est comment les références d'objets sont implémentées en Java. Pourquoi pouvez-vous définir votre propre référence tout en définissant une classe ? En même temps, si vous instanciez cette référence, cela ne mènera-t-il pas à une référence circulaire infinie ?

Ne vous inquiétez pas, analysons d'abord comment une référence est implémentée en Java :

Un accès de référence Java implique trois zones de mémoire : la pile JVM, le tas et la zone de méthode.

Prenons comme exemple la référence de variable locale la plus simple : Object obj = new Object() :

  • L'objet obj représente une référence locale, qui est stockée dans la table des variables locales de la pile JVM et représente une donnée de type référence

  • new Object() est stocké dans le tas en tant que données d'objet d'instance

  • L'adresse des informations de type de la classe Object (interface, méthode, champ, type d'objet, etc.) est également enregistrée dans le tas, et les données exécutées par ces adresses sont stockées dans la zone méthode ;

Il existe de nombreuses méthodes de mise en œuvre spécifiques, la poignée en fait partie et la relation est celle indiquée sur la figure.

Vous devriez le comprendre quand vous voyez cela. Les informations de la classe elle-même, les données d'instance de classe et les informations de référence pointant vers l'objet sont placées respectivement dans la zone de méthode, la zone de pile et la zone de tas de Java.

Dans l'exemple du sujet, la séquence de chargement java est la suivante :

  1. jvm charge d'abord la définition de classe dans la zone de méthode (mais la classe n'est pas instanciée pour le moment)

  2. Étant donné que public static final Direction FRONT = new Direction(); est une variable statique, cette variable sera également chargée dans la zone de méthode lorsque le jvm lit la définition de la zone de méthode pour la première fois.

  3. En même temps, cela signifie également que lors du chargement de cette variable, une instance de cette classe est également instanciée dans la zone du tas.

Faites attention au point clé ici, car la variable FRONT est une variable statique et la définition de classe chargée ne sera chargée qu'une seule fois, donc cette variable statique ne peut être chargée qu'une seule fois. Cela ne provoque pas de débordement de pile en raison de l'instanciation répétée de références circulaires telles que des variables non statiques.

大家讲道理

Je vous recommande de lire la réponse de R

Qu'est-ce qui vient en premier, Classe ou Objet ?
https://www.zhihu.com/questio...

Peter_Zhu

Dites-moi ce que vous comprenez, pourquoi ne pouvez-vous pas créer vos propres objets en classe ?
Après avoir ajouté du statique, ces variables deviennent des attributs de la classe et ne seront créées qu'une seule fois.

伊谢尔伦

Si vous ne pouvez pas créer vous-même, alors les autres classes ne le peuvent pas. Dans ce cas, comment instancier cette classe...

大家讲道理

Modèle de conception : modèle Singleton

PHPzhong

L'essence est un manque de compréhension de la programmation orientée objet en Java. Jetez un œil aux 23 modèles de conception et vous comprendrez peut-être

伊谢尔伦
  1. Constructor est aussi une méthode.

  2. Les méthodes avec private droits d'accès sont privées et visibles uniquement par cette classe.

Ainsi, cette classe peut instancier un objet en appelant le constructeur avec private droits d'accès.

巴扎黑

Raisons de l'utilisation des classes internes : chaque classe interne peut hériter indépendamment d'une implémentation (d'interface), donc si la classe externe a hérité d'une implémentation (d'interface), cela n'a aucun impact sur la classe interne. En fait, les classes internes implémentent efficacement « l'héritage multiple », c'est-à-dire que les classes internes permettent l'héritage de plusieurs types non-interfaces.

Nous savons que les classes internes ont automatiquement accès à tous les membres des classes externes, alors comment cela se fait-il ? Lorsqu'un objet de classe externe crée un objet de classe interne, l'objet de classe interne doit capturer secrètement une référence à cet objet de classe externe. Ensuite, lorsque vous accédez à un membre de la classe externe, vous utilisez cette référence pour sélectionner le membre de la classe externe. Bien sûr, ces détails sont gérés par le compilateur et la classe interne ici n'est pas statique.
Si une classe ne peut pas créer son propre objet de classe, alors à quoi sert votre classe ? Ah, hahahaha, je plaisante

Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal