我对java.Suppose中的对象创建有一个基本的疑问,我有两个类如下
Class B{
public int value=100;
}
Class A{
public B getB(){
return new B();
}
public void accessValue(){
//accessing the value without storing object B
System.out.println("value is :"+getB().value);
//accessing the value by storing object B in variable b
B b=getB();
System.out.println("value is :"+b.value);
}
}
我的问题是,存储对象和访问值是否会使内存方面有任何差异或两者相同?
答案 0 :(得分:3)
它们都是等价的,因为你两次都在实例化B
。第一种方式只是第二种方式的缩短版本。
答案 1 :(得分:2)
以下代码片段使用的是匿名对象。这在以后的代码中无法重用。
//accessing the value without storing object B
System.out.println("value is :"+getB().value);
下面的代码通过将对象分配给引用来使用该对象。
//accessing the value by storing object B in variable b
B b=getB();
System.out.println("value is :"+b.value);
内存和性能方面明显不同,只是在以后的版本中,堆栈帧有一个额外的指针。
答案 2 :(得分:1)
它是一样的。这样:B b = getB();只是让你的代码更具可读性。请记住,无论如何,该对象必须存储在内存中。
答案 3 :(得分:1)
如果你从不在这部分之后重复使用B-object,那么带有匿名对象的第一个选项可能更整洁:
如果您确实想再次访问B,则将其中一个存储在自己的变量中会更快。
编辑:嗯,我在打字时已经提到过这两点。答案 4 :(得分:0)
在这种情况下,差异(如果有的话)不值得一提。在第二种情况下,如果编译器没有优化它们,可能会生成额外的字节码或两个字节码,但任何体面的JIT几乎肯定会将这两种情况优化为相同的机器代码。
而且,无论如何,额外存储/负载的成本对于99.9%的应用程序来说是无关紧要的(在这种情况下由new
操作淹没)。
详细信息:如果查看字节码,在第一种情况下调用getB
方法并在堆栈顶部返回一个值。然后getfield
引用value
并将其放在堆栈顶部。然后完成StringBuilder append
以开始构建println
参数列表。
在第二种情况下,在astore
调用之后会有一个额外的aload
和getB
(指针存储/加载),并且StringBuilder的设置被卡在两者之间,所以副作用以源中指定的顺序发生。如果没有副作用担心编译器可能选择执行效率稍高的dupe
和astore
序列。在任何情况下,一个体面的JIT都会认识到b
从未再次使用并优化了商店。
答案 5 :(得分:0)
实际上,你只是给b的新对象引用的第二个实例没有区别。
所以代码方面如果使用版本1则无法实现println,因为在第二种情况下你没有任何引用,除非你不断为每个方法调用创建新对象。
答案 6 :(得分:0)
如果不查看生成的机器代码,您将无法说出差异。 可以是JIT将局部变量“b”放到堆栈上。然而,更有可能JIT将优化b。取决于您正在使用的JRE和JIT。在任何情况下,差异都很小,只有在特殊情况下才有意义。