在java中可以创建多少个嵌套的“新”对象?

时间:2014-02-25 19:10:33

标签: java oop object object-oriented-analysis

class car{
    Salon s ;
}
class Salon{
     Radio musicsystem ;
}
class Radio{
    Button play ;
}
class Button{
     String s ;
}

void main(){
    car mustang = new car( new Salon( new Radio(new Button ("fight club song"))))
}

我很容易想象有很多新的(新的(新的(新的......)))。你有多深? 我“直觉地”觉得编译器/ jvm /系统有太多级别的对象可能会很糟糕......

java对深度有限制吗?

5 个答案:

答案 0 :(得分:6)

应该是一个令人满意的答案,你可以比你希望在你的代码中看到的更深入。

如果你想为了它的乐趣而接受限制,我相信你实际上会遇到的第一个限制是单个方法的字节码长度的限制,它设置在一个非常低的64K

真正担心达到限制的唯一方法是,当你有递归构造函数调用时,例如在构造不可变链表或类似结构时可能会有。

答案 1 :(得分:2)

编译器对单个方法的限制为64 KB。这是因为跳转只能进入绝对字节代码位置并使用16位无符号值。即使您没有这样的跳跃,该限制也适用。

这会产生一些令人惊讶的后果。虽然您可能不希望以这种方式定义数千个嵌套对象,但您可能拥有一个生成的类,其中包含数千个ENUM值。这些值是在一个静态初始化方法中创建的,这也有相同的限制,因此您只能有大约3K枚举值。

更可能的限制是大型阵列。定义数组时,它实际上会生成用于设置每个单元格的代码。这是非常低效的,但一般。它还意味着您无法在Java中定义具有初始化值的数组,例如10K硬编码值。同样,这实际上只是生成代码的一个问题。

答案 2 :(得分:2)

不,这根本不是问题,尤其不是像你这样的人类可读水平。

让我们看看极限。像这样的代码:

public class Foo {
  public Foo(Foo f) {}
  public static void main(String[] args) {
    new Foo(new Foo(new Foo(new Foo(null))));
  }
}

编译成:

public static void main(java.lang.String[]);
Code:
   0: new           #2                  // class Foo
   3: dup           
   4: new           #2                  // class Foo
   7: dup           
   8: new           #2                  // class Foo
  11: dup           
  12: new           #2                  // class Foo
  15: dup           
  16: aconst_null   
  17: invokespecial #3                  // Method "<init>":(LFoo;)V
  20: invokespecial #3                  // Method "<init>":(LFoo;)V
  23: invokespecial #3                  // Method "<init>":(LFoo;)V
  26: invokespecial #3                  // Method "<init>":(LFoo;)V
  29: pop           
  30: return     

即。对于每个嵌套,它只使用操作数堆栈上的两个或多个元素:要实例化的类,嵌套对象以及随之传递的任何其他变量。

操作数堆栈的最大大小为implementation specific,但任何JVM肯定能够容纳数千个变量并高效地对它们进行操作。为了进行比较,javac在1000次嵌套后崩溃。

所以不,你的四级深度嵌套对于JVM来说绝对没有问题。

答案 3 :(得分:1)

堆内存的大小。当内存变满或GC无法收集对象时,它会抛出java.lang.OutOfMemoryError

所以只要你有记忆,这不是问题

答案 4 :(得分:1)

真的,这与写作没什么不同:

Button button = new Button ("fight club song");
Radio radio = new Radio(button);
Salon salon = new Salon(radio);
car mustang = new car(salon);

唯一的区别是你没有为每个引用分配一个变量,所以你以后不能引用它们。所以,答案是,只要你有足够的内存来实例化这些对象,你就可以创建任意多个。

这不是嵌套级别深层的问题,因为编译器调用每个构造函数,初始化对象,然后返回对初始化对象的引用。这里没有发生递归,堆栈也不会随着每个级别而增长。