La réponse la plus simple serait de créer un objet à chaque fois new A().
Analysons le processus légèrement plus détaillé 1 Une fois le programme exécuté, il entre d'abord dans la fonction main, puis l'exécute pour la première foisnew A(); 2. pas de constructeur affiché, le compilateur Lors de la compilation, un constructeur sans paramètre sera généré
public A(){
}
3. Après avoir entré le constructeur ci-dessus, vous devez d'abord initialiser les variables membres, c'est-à-dire A a = new A(); 4 Voici la clé du problème, s'il faut initialiser les variables membres A ou et continuez à appeler 2 Constructeur. new A()5. Ensuite, les étapes 2, 3 et 4 seront répétées jusqu'à ce que l'espace de pile de ce fil soit insuffisant et qu'une erreur soit générée. StackOverflowError
Ici, nous devons également vulgariser certaines connaissances sur l'appel de méthode. Dans
, chaque thread se verra attribuer un certain espace de pile (non partagé). Cet espace de pile peut être fixe ou étendu dynamiquement JVM. la mise en œuvre ici peut être différente. Chaque fois qu'une méthode est exécutée dans le thread, la méthode sera poussée dans la pile de threads sous la forme d'un cadre de pile. JVM
La raison pour laquelle
apparaît ci-dessus est que la méthode constructeur est appelée en permanence, puis les cadres de pile sont continuellement créés et poussés dans la pile de threads. Enfin, l'espace de pile n'est pas suffisant, provoquant un débordement de pile. StackOverflowError
Initialisation des variables et mécanisme de fonctionnement en mémoire
Initialisation des variables membres et mécanisme de fonctionnement en mémoire
Lorsque le système charge une classe ou crée une instance de la classe, le système alloue automatiquement de l'espace mémoire pour les variables membres et, après avoir alloué de l'espace mémoire, attribue automatiquement des valeurs initiales aux variables membres.
Initialisation des variables locales et mécanisme de fonctionnement en mémoire
Une fois les variables locales définies, elles doivent être explicitement initialisées avant de pouvoir être utilisées. Le système n'initialisera pas les variables locales. Cela signifie qu'une fois qu'une variable locale est définie, le système n'alloue pas d'espace mémoire pour la variable. Il n'allouera pas de mémoire pour la variable locale jusqu'à ce que le programme attribue une valeur initiale à la variable et enregistre la valeur initiale dans cette mémoire.
Code correct
public class A
{
public static void main(String[] args)
{
A a = new A();
}
}
java.lang.StackOverflowError
java.lang.StackOverflowError signifie un débordement de mémoire et une boucle infinie ; le questionneur ne doit pas créer une instance de classe A dans la classe A. A() est équivalent à un constructeur sans paramètre Écrivez A a = directement dans la classe A. new. A(); provoquera une création itérative infinie d'instances, conduisant finalement à un débordement de mémoire ; le message d'erreur indique également que le programme a une erreur à la ligne 4 et que l'erreur se produit à plusieurs reprises
Supplément de connaissances
Invitez le questionneur à venir sur ma page d'accueil pour acquérir des connaissances Java et échanger des conseils. Les points de connaissances mentionnés par le questionneur sont mentionnés dans l'orientation objet Java (partie 1) sur ma page d'accueil : https://segmentfault.com/a. /11 ...
Les deux personnes ci-dessus l'ont expliqué très clairement. Pour faire simple, vous ajoutez votre propre variable d'instance a à la classe A. Ce n'est pas un problème en soi, mais vous mettez l'initialisation de a dans le processus de initialisation de l'instance. , dans ce cas, tant que new A() est appelé une fois, il entrera dans une boucle d'appel infinie, donc la pile débordera.
Il s'agit d'un appel récursif très évident, et il n'y a pas de condition de fin, ce qui provoquera certainement un débordement de mémoire. La récursivité appelle la méthode elle-même dans la méthode, et le cas que vous avez donné est spécial, c'est une méthode constructeur, la raison est aussi simple que cela.
Le code ci-dessus est compilé en bytecode et traduit comme ceci :
La réponse la plus simple serait de créer un objet à chaque fois
new A()
.Analysons le processus légèrement plus détaillé
1 Une fois le programme exécuté, il entre d'abord dans la fonction
main
, puis l'exécute pour la première foisnew A()
;2. pas de constructeur affiché, le compilateur Lors de la compilation, un constructeur sans paramètre sera généré
3. Après avoir entré le constructeur ci-dessus, vous devez d'abord initialiser les variables membres, c'est-à-dire
Ici, nous devons également vulgariser certaines connaissances sur l'appel de méthode. DansA a = new A();
4 Voici la clé du problème, s'il faut initialiser les variables membres
A
ou et continuez à appeler 2 Constructeur.new A()
5. Ensuite, les étapes 2, 3 et 4 seront répétées jusqu'à ce que l'espace de pile de ce fil soit insuffisant et qu'une erreursoit générée.
StackOverflowError
, chaque thread se verra attribuer un certain espace de pile (non partagé). Cet espace de pile peut être fixe ou étendu dynamiquement
La raison pour laquelleJVM
. la mise en œuvre ici peut être différente. Chaque fois qu'une méthode est exécutée dans le thread, la méthode sera poussée dans la pile de threads sous la forme d'un cadre de pile.JVM
apparaît ci-dessus est que la méthode constructeur est appelée en permanence, puis les cadres de pile sont continuellement créés et poussés dans la pile de threads. Enfin, l'espace de pile n'est pas suffisant, provoquant un débordement de pile.
StackOverflowError
Initialisation des variables et mécanisme de fonctionnement en mémoire
Initialisation des variables membres et mécanisme de fonctionnement en mémoire
Lorsque le système charge une classe ou crée une instance de la classe, le système alloue automatiquement de l'espace mémoire pour les variables membres et, après avoir alloué de l'espace mémoire, attribue automatiquement des valeurs initiales aux variables membres.
Initialisation des variables locales et mécanisme de fonctionnement en mémoire
Une fois les variables locales définies, elles doivent être explicitement initialisées avant de pouvoir être utilisées. Le système n'initialisera pas les variables locales. Cela signifie qu'une fois qu'une variable locale est définie, le système n'alloue pas d'espace mémoire pour la variable. Il n'allouera pas de mémoire pour la variable locale jusqu'à ce que le programme attribue une valeur initiale à la variable et enregistre la valeur initiale dans cette mémoire.
Code correct
java.lang.StackOverflowError
java.lang.StackOverflowError signifie un débordement de mémoire et une boucle infinie ; le questionneur ne doit pas créer une instance de classe A dans la classe A. A() est équivalent à un constructeur sans paramètre Écrivez A a = directement dans la classe A. new. A(); provoquera une création itérative infinie d'instances, conduisant finalement à un débordement de mémoire ; le message d'erreur indique également que le programme a une erreur à la ligne 4 et que l'erreur se produit à plusieurs reprises
Supplément de connaissances
Invitez le questionneur à venir sur ma page d'accueil pour acquérir des connaissances Java et échanger des conseils. Les points de connaissances mentionnés par le questionneur sont mentionnés dans l'orientation objet Java (partie 1) sur ma page d'accueil : https://segmentfault.com/a. /11 ...
Les deux personnes ci-dessus l'ont expliqué très clairement. Pour faire simple, vous ajoutez votre propre variable d'instance a à la classe A. Ce n'est pas un problème en soi, mais vous mettez l'initialisation de a dans le processus de initialisation de l'instance. , dans ce cas, tant que new A() est appelé une fois, il entrera dans une boucle d'appel infinie, donc la pile débordera.
Il s'agit d'un appel récursif très évident, et il n'y a pas de condition de fin, ce qui provoquera certainement un débordement de mémoire. La récursivité appelle la méthode elle-même dans la méthode, et le cas que vous avez donné est spécial, c'est une méthode constructeur, la raison est aussi simple que cela.