对一组对象进行null转换是否要比转换为对象花费更多?

时间:2017-02-09 22:53:55

标签: java

我有以下课程

public void dump(Integer value){
    //do soemthing with value
}
public void dump(Integer[] values){
    //do soemthing with values
}

我想调用dump(null),我选择投射到什么并不重要,因为两者都按预期工作:

    dump((Integer[]) null);
    dump((Integer) null);
  1. 哪一个更好地使用资源(更少ram,cpu使用)?
  2. 我认为java会为null整数预分配4个字节,为Double分配8个字节,这是真的吗?
  3. 如果没有构造函数调用,那么其他(更复杂的)对象如何被置零呢?如何存储空值?

6 个答案:

答案 0 :(得分:8)

  
      
  1. 哪一个更好地使用资源(更少ram,cpu使用)?
  2.   

它不会产生任何可测量的差异。

  
      
  1. 我认为java会为null整数预分配4个字节,为Double分配8个字节,这是真的吗?
  2.   

没有。 Null为空。只有一种格式。你在这里混淆对象和引用。 null是一个参考。所有参考文献都是相同的大小。

  

其他(更复杂的)被取消的对象

怎么样?

没有“被取消的对象”这样的东西。

  

如果没有构造函数调用,那么如何存储空值?

作为空值。

答案 1 :(得分:2)

强制转换的类型不会影响null使用的内存。在反编译的类中:

aconst_null
checkcast     #4                  // class java/lang/Integer
invokevirtual #5                  // Method dump:(Ljava/lang/Integer;)V

VS

aconst_null
checkcast     #6                  // class "[Ljava/lang/Integer;"
invokevirtual #7                  // Method dump:([Ljava/lang/Integer;)

所以两者在内存使用方面都是一样的。

答案 2 :(得分:1)

我相信它们的成本是相等的,因为在这两种情况下你都没有实际的对象(Integer对象,Integer[]对象,它们的内存大小都不同。

这里你只有4字节的引用,它指向null,因为它为null。从这个角度来看,你在这些null - s。

中投射的类型没有区别

答案 3 :(得分:1)

  1. 没有区别。
  2. 不。 Java根本没有为null对象分配任何空间,因为null根据定义是对任何对象的引用。没有任何物体根本没有空间。引用本身总是32或64位长。
  3. 你是什么意思"存储"?引用变量保存指针值,该指针值始终具有相同的大小,与其指向的对象无关。无论对象的大小如何,即使引用指向非null值,引用大小也始终相同,无论它引用何种类型。它是地址的大小。我没看过,但我敢打赌,null引用是一个特殊的地址值,例如0,根据定义无处可寻。
  4. 投射引用不会更改引用。它仍然具有完全相同的值,一点一点,没有强制转换。

    所有这一切的唯一例外是64位Java的32位优化。通常,您希望64位Java中的所有引用都是64位长。但是,如果对程序的某些假设成立,您可以打开或关闭以32位保存引用的能力。但无论哪种方式,一旦JVM决定引用的宽度,32或64位,这将通过程序成立。

    所以底线,不,对其他类型的引用进行转换对引用所消耗的内存没有影响。

    如果对象的所有引用都超出范围或变为null,则对象消耗的内存可以变为零。

答案 4 :(得分:0)

所有参考值(以及盒装的整数和数组都是参考值)具有相同的表示形式,因此调用完全没有区别。如果成本存在差异,则会对所调用函数的实现进行处理。

答案 5 :(得分:-2)

  
      
  1. 哪一个更好地使用资源(更少ram,cpu使用)?
  2.   

如果你需要问自己这个问题,你总是可以写一个简单的测试。

Order

输出:

public class Main {
    private static Integer x = 0;
    private static final int n = 500000000;

    public static void dump(Integer value){
        x += 1;
    }
    public static void dump(Integer[] values){
        x += 1;
    }

    public static void main(String[] args) {
        long t = System.currentTimeMillis();
        for (int i = 0; i < n; i++) {
            dump((Integer[]) null);
        }
        long array_time = System.currentTimeMillis() - t;
        t = System.currentTimeMillis();
        for (int i = 0; i < n; i++) {
            dump((Integer) null);
        }
        long int_time = System.currentTimeMillis() - t;
        System.out.println("array_time: " + array_time + " ms");
        System.out.println("int_time: " + int_time + " ms");
    }
}

没有显着差异。