这可能是一个非常明显的问题,但我无法完全理解它。
我开始实现自己的树结构,并认为每个节点都需要将其父/子保存在其自身内部。以下是代码的简化版本:
public class Container {
public String name;
public String type;
public Container child;
public Container(String name, String type){
this.name = name;
this.type = type;
}
public void createChild(String name, String type){
this.child = new Container(name, type);
}
}
问题是这一行Container child;
和this.child = new Container(name, type);
如何运作?
对我而言,它似乎是一个鸡与蛋的问题,这是定义对象的类,但它仍然可以抢先保持自己的对象,如果是这种情况,那么它所拥有的对象应该保持它自己的孩子等等。在尝试为Container对象分配内存时,这会导致(在我看来)一个递归问题。
答案 0 :(得分:8)
您显示的代码中没有递归。
构造函数将name
和type
字段指定为参数化。
createChild
将构造函数用于Container
类的新实例,然后将其分配给当前Containter
实例的child
变量。
构造函数递归是指构造函数在第一行调用自身,或者在检测到循环调用时(构造函数A调用构造函数B,再次调用构造函数A),这两者都不会编译。
值得注意
IF 你在构造函数中调用createChild
,然后你会有(坏)递归,你的代码可能会因JVM错误而失败(很可能)一个StackOverflowError
,但Holger提及它也可能是OutOfMemoryError
)。
这是因为构造函数会以递归方式调用自身,并且编译器不够“聪明”到足以检测到它,因此它会通过编译但在运行时失败。
答案 1 :(得分:4)
您的Container child
声明不构造Container
个实例;它只是声明了一个可用于引用Container
的字段,但引用最初是null
。所以你不要进入递归。
答案 2 :(得分:0)
其他答案已正确识别出没有发生递归,因为构造函数未填写子字段。但他们没有特别说明:
这导致(在我看来)尝试分配时的递归问题 Container对象的内存。
对于子引用的对象没有内存分配(因为它是一个空引用),这就是为什么当你第一次构造它的实例时你的类不会导致递归的原因。
答案 3 :(得分:0)
首先,您必须知道我们在这里谈论 HAS-A关系:
Has-A表示一个类的实例“具有”对实例的引用 另一个类或同一个类的另一个实例。
即使它是同一个类,但内存中有两个不同的实例(在你的情况下)或maybo三个或更多......
在你的情况下,khow解决这个理解问题的最重要的事情是构造函数调用的序列。
1-容器构造函数(创建包装容器)
2- ChildContainer构造函数(创建子容器并设置关系 HAS-A )
答案 4 :(得分:0)
问题是这一行
Container child;
和this.child = new Container(name, type);
如何运作?
因为它是recursive data type而Java允许你这样做。