Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
有多少个嵌套的;新";可以用java创建对象吗?_Java_Oop_Object_Object Oriented Analysis - Fatal编程技术网

有多少个嵌套的;新";可以用java创建对象吗?

有多少个嵌套的;新";可以用java创建对象吗?,java,oop,object,object-oriented-analysis,Java,Oop,Object,Object Oriented Analysis,我可以很容易地想象有很多新的(新的(新的…))。你能走多深? 我“直觉地”觉得编译器/jvm/系统有太多级别的对象是不好的 java对深度有限制吗?一个令人满意的答案应该是,您可以深入到比您希望在代码中看到的实际情况更深的地方 如果你只是为了好玩而考虑限制,我相信你实际上会达到的第一个限制是单个方法字节码的长度限制,它被设置为非常低的64K 真正担心达到极限的唯一方法是当您有递归构造函数调用时,例如您在构造不可变链表或类似结构时可能会遇到这种情况。堆内存的大小。当内存已满或GC无法收集对象时,它

我可以很容易地想象有很多新的(新的(新的…))。你能走多深? 我“直觉地”觉得编译器/jvm/系统有太多级别的对象是不好的


java对深度有限制吗?

一个令人满意的答案应该是,您可以深入到比您希望在代码中看到的实际情况更深的地方

如果你只是为了好玩而考虑限制,我相信你实际上会达到的第一个限制是单个方法字节码的长度限制,它被设置为非常低的64K


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

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


因此,只要你有记忆,这就不是问题。实际上,这与写作没有什么不同:

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"))))
}
唯一的区别是没有为每个引用指定变量,因此以后不能引用它们。因此,答案是,只要您有足够的内存来实例化这些对象,就可以创建任意数量的对象


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

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

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


更可能的限制是大型阵列。定义数组时,它实际上会生成代码来设置每个单元格。这是相当低效的,但一般。这也意味着你不能用Java定义一个数组,用初始化值,比如说10K硬编码值。同样,这实际上只是生成代码的一个问题。

不,这根本没有问题,尤其是在像您这样的人类可读级别上

不过,让我们看看限制。代码如下:

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

public class Foo {
  public Foo(Foo f) {}
  public static void main(String[] args) {
    new Foo(new Foo(new Foo(new Foo(null))));
  }
}
publicstaticvoidmain(java.lang.String[]);
代码:
0:new#2//class Foo
3:dup
4:新的#2//class Foo
7:dup
8:新的#2//class Foo
11:dup
12:新的#2//Foo类
15:dup
16:aconst_null
17:invokespecial#3//方法“”:(LFoo;)V
20:invokespecial#3//方法“”:(LFoo;)V
23:invokespecial#3//方法“”:(LFoo;)V
26:invokespecial#3//方法“”:(LFoo;)V
29:流行音乐
30:返回
i、 对于每个嵌套,它只使用操作数堆栈上的两个或多个元素:要实例化的类、嵌套对象以及随其传递的任何其他变量

操作数堆栈的最大大小为,但任何JVM都肯定能够容纳数千个变量并高效地对其进行操作。相比之下,
javac
在1000次嵌套后崩溃


因此,您的四级深度嵌套对JVM来说绝对没有问题

只要你有记忆。这不是编译器的问题。你到底为什么要写这样的代码?@RohitJain,这只是一个例子,我看到了3个新的嵌套对象,所以我很好奇创建没有限制。@SotiriosDelimanolis在某个时候它一定会成为编译器的问题。但在此之前,您将达到64K方法大小限制。这不适用吗@JasonSperske不,所有这些
news
的调用堆栈仍然只有一个(除非它们自己在构造函数中调用方法)。@TomG但是,在一个稍微不同的场景中,如我所提到的,
new
将从构造函数中调用,然后它确实适用。@MarkoTopolnik更正,这就是我所说的,除非那些构造函数继续调用方法。但是,通过方法调用提供参数不会增加调用堆栈,因为提供参数的方法在调用构造函数后已经返回。因此,您担心的不是新的
new
s,而是递归的方法参数?因此,理论上可以不使用任何大小的方法,如果没有跳跃的话?数组和枚举填充看起来确实是这样。我还听说,
javac
可以得到增强,自动生成一个方法调用链,每个方法的大小都合适。@MarkoTopolnik方法链更有意义,因为默认情况下,大于8K的方法从不进行jit。更有意义的是JVM取消了字节码的限制但这需要对字节码进行彻底的重新设计——考虑到由于字节码而真正停止使用的用例数量,可能不值得这么麻烦。还有其他一些东西,如
start\u pc
end\u pc
属性,它们也接受16位数组索引。但我不认为这是最主要的一点——这一点根本不涉及字节码,没有一个非常严重的原因,例如
invokedynamic
——这可能是自Java 1.0以来引入的唯一指令。@MarkoTopolnik true,可能需要做一些更改,但是我认为为新的类版本格式扩展类型是一个相对简单的改变。有没有零钱
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