Method threw ‘java.lang.StackOverflowError‘ exception. Cannot evaluate 问题

博客讨论了在Java编程中遇到的A类与B类1:n关系导致的StackOverflowError问题。由于类间的互相引用,在执行对象添加操作时触发无限递归的toString()调用。解决方法是在类中重写toString()方法,避免打印互相引用的成员变量,从而消除循环调用。提供的代码示例展示了问题修复后的A类和B类实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 一、背景

今天在做项目中发现A类与B类的关系是1:n,即A类中有一个List<B> bList的成员变量,B类中有一个A a的成员变量。

当执行A.getBList().add(b)方法时会报错:Method threw 'java.lang.StackOverflowError' exception. Cannot evaluate com.saint.start.gaia.A.toString()

二、原因

StackOverFlow问题,顾名思义是栈溢出的意思,Java虚拟机在实际调用方法时会设置最大栈深度,防止其暴走直接占用满所有内存。

根本上是因为实例之间的互相引用!和Spring中的循环依赖很相似。

因为Debugger会调用对象的toString()方法以显示对象中的所有数据信息。然后,我的所有对象都使用lombok的@Data注解重写了toString()方法。问题就出在这里,这意味着程序会不断地调用A类和B类的toString()方法,永不停止,结果就造成了StackOverFlow的问题。
 

三、解决方案

在类中重写toString()方法,不打印互相引用的类成员变量,避免这种循环调用的产生。

 

四、实例

// A类
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.List;

/**
 * @author Saint
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Address {
    private String name;
    private List<User> userList;

    @Override
    public String toString() {
        return name;
    }
}

// B类
/**
 * @author Saint
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
class User {
    private String name;

    private Address address;

    @Override
    public String toString() {
        return name;
    }
}

// main方法
public class Main {

    public static void main(String[] args) {
        Method m = new Method();
        Address address = new Address("nanjing", new ArrayList<>());
        User ha = new User("ha", address);
        address.getUserList().add(ha);
        User user = new User("start", address);
        address.getUserList().add(user);
    }
}
wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

秃秃爱健身

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值