我从琐碎的减法中得到编译错误
Long result;
int operand1 = 10;
int operand2 = 5;
result = operand1 - operand2;
从最后一行:
incompatible types: int cannot be converted to java.lang.Long
除了我相信它可以被转换为什么是最好的解决方案?以下任何一个都会编译,但看起来很尴尬
result = (long) operand1 - operand2;
result = (long) (operand1 - operand2);
result = new Long (operand1 - operand2);
result = Long.valueOf(operand1 - operand2);
哪一个最适合表现?
答案 0 :(得分:1)
由于您没有创建任何对象,因此前两行应该是性能最佳的。 'long'是原始数据类型,而'Long'是长期的包装类。在前两个之间,我会说第二个有点快,因为你在整数上减去然后将一个值转换为long,而在第一个 - 你将两个值转换为long然后再减去longs这会慢一些。
关于编译问题 - 原始类型会自动转换为更大的类型,即如果减去它们,int将转换为long。但是,如果将该int的值赋给Long类对象,则会出现编译错误,因为不会发生自动转换,因此您必须手动将int原语转换为long原语或Long对象。
答案 1 :(得分:1)
2和4基本相同。如果他们生成相同的字节码,我不会感到惊讶。
1与2和4在性能方面几乎相同,但如果2和4中的整数减法溢出,它可能会产生稍微不同的答案。
Long.valueOf((long) op1 - (long) op2)
Long.valueOf((long) (op1 - op2))
我唯一要避免的是3,因为肯定会产生一个新值,而其他可能使用缓存值,具体取决于{{3的实现}}:
[
Long.valueOf
]返回表示指定long值的Long实例。如果不需要新的Long实例,此方法通常应优先于构造函数 Long(long)使用,因为此方法可能通过缓存频繁请求的值来显着提高空间和时间性能。请注意,与Integer类中的相应方法不同,不需要此方法来缓存特定范围内的值。
答案 2 :(得分:1)
让我们看一下javac 1.8.0_66生成的字节码:
(result
分配给广告位1,operand1
位于广告位2中,operand2
位于广告位3中)
方法1:
result =(long)operand1 - operand2;
5: iload_2
6: i2l
7: iload_3
8: i2l
9: lsub
10: invokestatic #2 // Method java/lang/Long.valueOf:(J)Ljava/lang/Long;
13: astore_1
方法2:
result =(long)(operand1 - operand2);
14: iload_2
15: iload_3
16: isub
17: i2l
18: invokestatic #2 // Method java/lang/Long.valueOf:(J)Ljava/lang/Long;
21: astore_1
方法3:
result = new Long(operand1 - operand2);
22: new #3 // class java/lang/Long
25: dup
26: iload_2
27: iload_3
28: isub
29: i2l
30: invokespecial #4 // Method java/lang/Long."<init>":(J)V
33: astore_1
方法4:
result = Long.valueOf(operand1 - operand2);
这产生与方法2完全相同的字节码。为简洁而省略。
如您所见,所有四种方法构建了一个新的Long
对象,因为Long.valueOf()
将调用new Long()
(尽管Long.valueOf()
将Long
个对象缓存为-128到127之间的值(至少在Java 1.8.0_66中)。如果值超出该范围,则调用构造函数实际上很小因为它绕过了缓存检查,所以有点快!)。
方法5: 如果您对速度感兴趣,请不要使用自动装箱,而是使用原始类型。这是改变:
结果很长; //不长
并且原始声明在没有编译器投诉的情况下工作:
result = operand1 - operand2;
6: iload_3
7: iload 4
9: isub
10: i2l
11: lstore_1
如本页其他地方所述,可能存在溢出问题:首先减去整数,然后将其转换为长整数。最好只对所有3种类型使用long
(这将跳过上面的i2l
。)