• 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

  • 相关阅读:
    你不知道的JavaScript--Item17 循环与prototype最后的几点小tips
    你不知道的JavaScript--Item16 for 循环和for...in 循环的那点事儿
    JavaScript (Array) map 方法
    你不知道的JavaScript--Item15 prototype原型和原型链详解
    JavaScript prototype原型和原型链详解
    你不知道的JavaScript--Item14 使用prototype的几点注意事项
    JavaScript 数组详解
    Android 高清加载巨图方案 拒绝压缩图片
    解决运行nodejs代码Error: listen EADDRINUSE
    linux上使用netstat查看当前服务和监听端口
  • 原文地址:https://www.cnblogs.com/Xieyang-blog/p/8306480.html
Copyright © 2020-2023  润新知