Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/352.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/14.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_Arrays_Inline - Fatal编程技术网

用Java内联声明数组是否更快(或更好)?

用Java内联声明数组是否更快(或更好)?,java,arrays,inline,Java,Arrays,Inline,考虑以下两个几乎相等的方法调用。注意字节数组在这两个节点上的声明和分配方式 void Method1() { byte [] bytearray = new byte[16]; /* some code */ } void Method2() { byte [] bytearray = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; /* some code */ } 在这两种情况下,假设Method1和Method2返回时

考虑以下两个几乎相等的方法调用。注意字节数组在这两个节点上的声明和分配方式

void Method1()
{
    byte [] bytearray = new byte[16];

    /* some code */

}

void Method2()
{
    byte [] bytearray = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};

    /* some code */    
}
在这两种情况下,假设Method1和Method2返回时,“bytearray”是垃圾收集的候选对象,因为操纵bytearray变量的代码都不会持有超过方法本身结尾的引用


方法2是否通过避免调用“new”而运行得更快(或不同)?或者上述两种实现是等效的?在这两种情况下,Java编译器或运行时是否可以进行优化,以避免为这个短暂的临时缓冲区命中内存分配器的开销?

这两种方法完全等效。但是,第二种方法更为详细,对于较长的数组或者如果您想修改数组长度,则不太方便。

它们是相同的

new
关键字创建一个对象。但在Java中,数组是。。物体。见:

在Java编程语言中,数组是对象(§4.3.1),是 动态创建,并可分配给Object类型的变量 (§4.3.2). 类对象的所有方法都可以在数组上调用。
..
数组是由数组创建表达式或数组初始值设定项创建的


这两种方法没有区别。这只是语法上的问题。

最好使用第一种样式

在第二种风格中,我试图找到一个非0。它保证了更无错误,因此可读性更好


这个速记有很好的理由存在

两者都是相同的…因为它们都将在堆上占据相同的空间…字节码将是很好地研究它的选项

两者都是相同的,但我不推荐第二个,因为读写和调试都很困难。想象一下,你会发现:

byte [] bytearray = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
你能告诉我数组的大小是否正确吗?是的,但想象一下:

byte [] bytearray = new byte[25];
这要容易得多


想象一下,数组长度是100

哪种形式最快?取决于JIT-它们可能是等价的。如果有的话,很少有程序会注意到差异

哪种形式最好?几乎总是让程序更具可读性的形式

但是,不管我们是否注意到,有什么实际的区别吗?让我们看看

class ArrayTest {

    public int[] withNew() {
        int[] arr = new int[4];
        return arr;
    }

    public int[] withInitializer() {
        int[] arr = {0, 0, 0, 0};
        return arr;
    }

}
我们使用
javap-carrayTest
来分解它:

Compiled from "ArrayTest.java"
class ArrayTest {
  ArrayTest();
    Code:
       0: aload_0       
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return        

  public int[] withNew();
    Code:
       0: iconst_4      
       1: newarray       int
       3: astore_1      
       4: aload_1       
       5: areturn       

  public int[] withInitializer();
    Code:
       0: iconst_4      
       1: newarray       int
       3: dup           
       4: iconst_0      
       5: iconst_0      
       6: iastore       
       7: dup           
       8: iconst_1      
       9: iconst_0      
      10: iastore       
      11: dup           
      12: iconst_2      
      13: iconst_0      
      14: iastore       
      15: dup           
      16: iconst_3      
      17: iconst_0      
      18: iastore       
      19: astore_1      
      20: aload_1       
      21: areturn       
}
尽管这会编译成另一组字节码,它们基本相同,但并不完全相同:

  public int[] withNewAndSettingExplicitly();
    Code:
       0: iconst_4      
       1: newarray       int
       3: astore_1      
       4: aload_1       
       5: iconst_0      
       6: iconst_0      
       7: iastore       
       8: aload_1       
       9: iconst_1      
      10: iconst_0      
      11: iastore       
      12: aload_1       
      13: iconst_2      
      14: iconst_0      
      15: iastore       
      16: aload_1       
      17: iconst_3      
      18: iconst_0      
      19: iastore       
      20: aload_1       
      21: areturn 
因此,这个故事的寓意是:如果你想让所有元素都设置为
0
,你就可以用
new int[size]
生成更少的字节码(这可能更快,也可能更快),但你还必须输入更少的字节码(这是一个巨大的胜利)。如果要在分配数组时直接设置数组中的值,请使用代码中看起来最好的值,因为生成的代码将与您选择的任何形式几乎相同

现在,回答您的实际问题:

方法2是否通过避免调用“new”而运行得更快(或不同)

正如我们所看到的,
new
隐藏在初始化器语法后面(查找
newarray
op代码)。顺便说一句,JVM中的分配非常便宜(分代垃圾收集器具有令人愉快的副作用)

或者上述两种实现是等效的

正如我们所看到的——不完全如此,但不太可能有人会注意到其中的差异

在这两种情况下,Java编译器或运行时是否可以进行优化,以避免为这个短暂的临时缓冲区命中内存分配器的开销

再说一次-分配很便宜,所以不要担心。然而,最近的JVM有一个称为的小特性,这可能导致数组被堆栈分配,而不是堆分配

事实上,它们并不生成相同的字节码,尽管它们在功能上是等价的。
  public int[] withNewAndSettingExplicitly();
    Code:
       0: iconst_4      
       1: newarray       int
       3: astore_1      
       4: aload_1       
       5: iconst_0      
       6: iconst_0      
       7: iastore       
       8: aload_1       
       9: iconst_1      
      10: iconst_0      
      11: iastore       
      12: aload_1       
      13: iconst_2      
      14: iconst_0      
      15: iastore       
      16: aload_1       
      17: iconst_3      
      18: iconst_0      
      19: iastore       
      20: aload_1       
      21: areturn