一、背景

今天在做项目中发现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==

 

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐