public class CodeBlock02
{
{
System.out.println("第一代码块");
}
public CodeBlock02()
{
System.out.println("构造方法");
}
{
System.out.println("第二构造块");
}
public static void main(String[] args)
{
new CodeBlock02();
new CodeBlock02();
new CodeBlock02();
}
}
在这里, new CodeBlock02()
; 或者换成 CodeBlock02 code = new CodeBlock02();
他们是一样的吗!
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 le questionneur se demande, c'est ce que sont les références d'objets en Java et quelle est leur relation avec le processus d'instanciation des objets.
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 de la question :
le code est une référence stockée dans la table des variables locales, qui pointe vers les données d'instance d'objet dans le tas. Ces données d'instance d'objet sont obtenues via
new CodeBlock02()
.Un peu plus précis :
Pour résumer, le code est la "télécommande" que vous utilisez pour recevoir l'instance produite par new. Elle pointe vers l'emplacement spécifique de cet objet dans la zone du tas.
Vous devez comprendre les références
de JavaCode CodeBlock02 = nouveau CodeBlock02();
Celle de gauche s'appelle une variable de type CodeBlock02.
Celui de droite s'appelle un objet de type CodeBlock02.
Vous pouvez également laisser cette variable pointer tour à tour vers deux objets différents du même type.
Vous pouvez même faire pointer des variables de ce type vers des objets de sous-classes de ce type :
Vous pouvez également appeler des méthodes directement sur l'objet créé par new comme ceci :
Les deux sont des objets de déclaration. Ce que l'affiche demande devrait être une affectation
Si vous ne continuez pas à opérer sur cette valeur par la suite, ce sera pareil que vous l'attribuiez ou non
new CodeBlock02() // Si aucune valeur n'est attribuée après la déclaration, il n'y a aucun moyen de continuer à fonctionner sur cet objet
CodeBlock02 code = new CodeBlock02(); // Attribue l'objet déclaré à une variable, et suivant des opérations peuvent être effectuées
Celle de gauche est la variable de référence de l'objet, et celle de droite est l'objet effectivement alloué dans la mémoire.