【问题标题】:No. of Objects created in Java用 Java 创建的对象数
【发布时间】:2014-11-18 18:30:05
【问题描述】:

在下面提到的 4 种情况下,创建了多少个对象?

int[] array = new int[10];

String[]  str = new String[10];

Edit 1 : 

String[] str = { "1", "2", "3", "4", "5", "6", "7", "8", "9", "10" };

Edit 2 : 


String[] str1 = new String[10]; 

    for(int i = 0;i<10;i++){
         str1[i] = "Str";
    }

【问题讨论】:

  • 只会为此创建 2 个数组对象。
  • 每次使用“new”时,都会创建 1 个新对象。而已。只要不填满这些数组,就只是分配了空间。
  • Miche 是正确的,尽管可以隐藏“new”的使用.. 在另一个对象构造函数或简写数组语法中
  • @Miche :如果那些被 10 个字符串填充,那么它不会在字符串类型数组的情况下生成 11 个对象
  • 如果你用 Int 等原始类型填充数组,那么将只有一个对象(数组),但如果你用字符串等对象填充它们,那么实际上你将拥有这 10 个对象 + 数组。然而,这只是概念层面,在内存管理方面并没有多大意义。

标签: java


【解决方案1】:

2 Array 对象被创建。

int[] array = new int[10];// can hold 10 ints

String[]  str = new String[10]; // can hold references to 10 Strings

【讨论】:

    【解决方案2】:

    Java 数组是单个对象。并且分配一个新数组只能分配一个对象。分配可以嵌套,通过在数组初始化块中写入 new、自动装箱或通过对象构造函数也以链式操作的形式调用 new。

    您的三个案例的答案是:1、1 和 1。下面的详细信息,以及一些突出特殊案例的其他示例。

    字符串和自动装箱的整数也可以是特殊情况,因为 JVM 对它们有特殊的缓存。以下注释示例中的详细信息:

    // 1 object, an array with 10 elements (set to zero)
    int[] array = new int[10]; 
    
    // 1 objects, an array with 10 elements (set to null)
    String[]  str = new String[10];  
    
    // 1 object, an array with 10 elements pointing at objects 
    // that have been preallocated within the String pool.  See 
    // the appendium below for evidence.
    String[] str = { "1", "2", "3", "4", "5", "6", "7", "8", "9", "10" }; 
    
    // 3 objects, one for the array and one per integer.
    Integer[] a4 = new Integer[] { new Integer(1), new Integer(2) }; 
    
    // 1 object again, Java has an Integer pool of limited size which is used
    // to optimise auto boxing; 1 and 2 will definitely be within that default
    // range
    Integer[] a6 = new Integer[] { 1, 2 }; 
    
    // 3 objects, the default size of the int pool is fairly low
    // but it can be increased via a JVM flag.
    Integer[] a5 = new Integer[] { 1000, 2000 }; 
    
    // 3-5 objects -- 1 for the array, one for each of the string objects and 1 
    // per char array backing the string.  Depending on JVM version the char 
    // array may be shared with the interned strings, so that one is a little tricky
    // and is why I said 3-5.
    String[] str = {new String("1"), new String("2")};  
    

    附录

    只是为了好玩,这里是常量池的证据。

    下面的 Java 代码编译成下面的字节码,注意只有数组被分配。元素使用类池常量。我已经缩短了输出,它只是为每个元素重复相同的代码(dup,iconst,ldc,aastore,...)

    java代码:

    String[] str = { "1", "2", "3", "4", "5", "6", "7", "8", "9", "10" }; 
    

    JVM字节码:

       0: bipush        10
       2: anewarray     #2                  // class java/lang/String
       5: dup           
       6: iconst_0      
       7: ldc           #3                  // load constant from class pool - String 1
       9: aastore                           // store into array
      10: dup           
      11: iconst_1      
      12: ldc           #4                  // String 2
      14: aastore       
      15: dup           
      16: iconst_2      
    

    【讨论】:

      【解决方案3】:

      正如其他人所说,您的前两个语句分别创建 1 个对象(一个数组)。

      第三个有点特别。您创建一个字符串数组(1 个对象),其中填充了对 10 个字符串(10 个对象)的引用。所以,这是 11 个对象。

      虽然不完全。 Java 中的字符串文字是池化的,这基本上意味着内存中有一个特殊的位置保存所有字符串文字。因此,如果您在代码中的两个不同位置使用字符串"string",那么您都指的是同一个对象。如果您使用字符串字面量,就不能真正说正在创建新对象。

      即使你确实这么说了(因为如果它们在你的代码中没有被使用,它们就不会“存在”在池中)这意味着第三行是否“创建”新对象基本上取决于有多少这些字符串也用于程序的其他地方。

      【讨论】:

        猜你喜欢
        • 2020-12-17
        • 2021-07-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-03-27
        • 1970-01-01
        相关资源
        最近更新 更多