Java關於使用“final”修飾基本類型的注意事項


今天無意發現這樣一道題,可以先做做看:

正確答案是BCD。

 

至於原因有人給出了參考答案:

1、所有的byte,short,char型的值將被提升為int型;

2、如果有一個操作數是long型,計算結果是long型;

3、如果有一個操作數是float型,計算結果是float型;

4、如果有一個操作數是double型,計算結果是double型;

5、被fianl修飾的變量不會自動改變類型,當2個final修飾相操作時,結果會根據左邊變量的類型而轉化。
 
其中第5項就很模糊了,啥叫 根據左邊的變量而變化??
在此做出以下測試:
 
 1 public class Test1
 2 {
 3     public static void main(String[] args) {
 4         
 5         final byte a1=1,b1=1,b11;
 6         final char a2='a',b2='a',b22;
 7         final short a3=3,b3=3,b33;
 8         final int a4=4,b4=4,b44;
 9         final long a5=5,b5=5,b55;
10         final float a6=6,b6=6,b66;
11         final double a7=7,b7=7,b77;
12         
13         //等號右邊,被final修飾的為byte,short,char,int中的任何一種;等號左邊可以為byte、short、char、int、long、float、double中的任何一種都不會出錯
14         b11=a1+a2;
15         b11=a2+a3;
16         b22=a3+a3;
17         b33=a4+a3;
18         b44=a2+a3;
19         b55=a1+a3;
20         b66=a2+a3;
21         b77=a4+a3;
22         
23         //等號右邊,被final修飾的為long、float、double中的任何一種;等號左邊類型必須等於或者高於等號右邊類型才不會出錯,否則出錯。 
24         b11=a4+a5;   //編譯時出錯 類型不匹配:不能從 long 轉換為 byte
25         b22=a5+a5;   //編譯時出錯 類型不匹配:不能從 long 轉換為 char
26         b33=a5+a5;   //編譯時出錯 類型不匹配:不能從 long 轉換為 short
27         b44=a5+a5;   //編譯時出錯 類型不匹配:不能從 long 轉換為 int
28         b55=a6+a6;   //編譯時出錯 類型不匹配:不能從 float 轉換為 long
29         b66=a5+a6;
30         b77=a7+a2;
31     }
32 }

 

 以上結論正確?正確了一半,這只是在找規律並不能解釋所有情況,例如:

1         final byte a = 126;
2         final int b = 2;
3         
4         byte x = a+b; // 編譯出錯  不能從 int 轉換為 byte

 

為什么錯誤?

因為,final修飾的變量其實為常量,即在編譯期間的時候就已經確定為一個具體的不變的東西,所以以上代碼在運行的時候直接相當於 byte x = 126 + 2;【byte 范圍為-128~127】

而byte x = 122 + 5;就不會有錯。

但是要注意的是,long、float、double替換成相應常量時候會自動帶上標識L、F、D,所以我們平時帶入這三種時記得帶上標識。例如12L、12.0F、12.0D。

int y = 12D + 12L; // 編譯出錯  不能從 double 轉換為 int

 

額外的,我們需要提醒一些情況【與final無關】

1         int x = 2147483647 + 2147483647; // 正確 【2147483647為int最大值】
2         int y = 2147483648; // 類型 int 的文字 2147483648 超出了范圍

 

第一行代碼,右邊計算溢出,但是由於底層默認采用int補碼進行運算,最后得到的補碼再還原,值為-2再賦值給左邊,所以不會報錯,而第二行直接就溢出了。

【如需計算,則將右邊其中一個2147483647加上L(變為long),並且將x聲明為long即可使用long的補碼計算】

 

綜上所述,其實有關【使用“final”修飾基本類型】並不需要分太多情況,

直接將final那個變量名用其常量值進行帶入,再判斷是否發生各種錯誤即可。

 

這時候,我們再回到最開始的那道題就很好解了:

  1. b3=(b1+b2);  /*語句1*/  ——>  b3 = b1+ b2;  // 錯,右邊整形計算默認使用int,最終為int  而左邊為byte類型,大變小需要強轉
  2. b6=b4+b5;    /*語句2*/   ——>  b6 = 4+ 6;      //正確
  3. b8=(b1+b4);  /*語句3*/  ——>  b8 = b1+ 4;  // 錯,同1
  4. b7=(b2+b5);  /*語句4*/  ——>  b7 = b2+ 6;  // 錯,同1

最后附上等號右邊變量計算最終類型表:(直接寫則整形為int,小數為double)

全為整形:無long——int        例如(byte)a +(short)b + 1

     有long———long      例如(byte)a +(short)b + 1 + (long)d

包含小數:無double——float      例如(byte)a +(short)b + 1 + (long)d + (float)e

     有doule——double      例如(byte)a +(short)b + 1 + (long)d + (float)e + 1.0


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM