[英]java autoboxing from int to java.lang.Long casting issue
我從平凡的減法中得到編譯錯誤
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);
哪個最適合表現?
前兩行應該是最佳性能,因為您沒有創建任何對象。 “ long”是原始數據類型,而“ Long”是long的包裝類。 在前兩個之間,我想說第二個要快一點,因為對int進行減法,然后將單個值轉換為long,而在第一個中,將兩個值都轉換為long,然后對longs進行減法這會有點慢。
關於編譯問題-基本類型會自動轉換為更大的類型,即如果減去它們,int會轉換為long。 但是,如果將那個int的值分配給Long類對象,則會得到編譯錯誤,因為不會發生自動轉換,因此,您必須手動將int原語轉換為Long原語或Long對象。
2和4基本相同。 如果它們產生相同的字節碼,我不會感到驚訝。
1在性能方面將與2和4幾乎相同,但是如果2和4中的整數減法溢出,則可能會產生稍微不同的答案。
Long.valueOf((long) op1 - (long) op2)
Long.valueOf((long) (op1 - op2))
我唯一要避免的是3,因為這肯定會產生一個新值,而其他人可能會使用一個緩存的值,這取決於Long.valueOf
實現:
[
Long.valueOf
]返回一個Long實例,它表示指定的long值。 如果不需要新的Long實例,則通常應優先於構造方法 Long(long)使用此方法,因為此方法通過緩存經常請求的值可能會產生明顯更好的空間和時間性能。 請注意,與Integer類中的相應方法不同, 不需要此方法來緩存特定范圍內的值 。
讓我們看一下javac 1.8.0_66生成的字節碼:
( result
被分配給時隙1, operand1
是在時隙2,和operand2
在插槽3)
方法1:
結果=(長)操作數1-操作數2;
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
方法二:
結果=(長)(操作數1-操作數2);
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:
結果=新的Long(操作數1-操作數2);
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:
結果= Long.valueOf(operand1-操作數2);
這產生與方法2完全相同的字節碼。為簡潔起見,省略了它。
如您所見,這四種方法都構造了一個新的Long
對象,因為Long.valueOf()
將調用new Long()
(盡管Long.valueOf()
緩存Long
對象的值介於-128和127之間(至少在Java 1.8中如此)。 0_66)。如果值超出該范圍,則調用構造函數實際上要快一點,因為它繞過了緩存檢查!
方法5:如果您對速度感興趣,請不要使用自動裝箱,而應使用原始類型。 這是更改:
結果長 // 不久
並且原始語句在沒有編譯器投訴的情況下有效:
結果=操作數1-操作數2;
6: iload_3
7: iload 4
9: isub
10: i2l
11: lstore_1
如本頁其他地方所述,可能存在溢出問題:首先將int減去,然后將其轉換為long。 最好對所有3種類型都使用long
類型(這將跳過上面的i2l
)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.