• Java语法基础(2)


    一、变量与常量

    1、标识符与关键字

    (1). 标识符

    标识符可以简单的理解为一个名字,用来标识类名、变量名、方法名、数组名、文件名的有效字符序列。如图所示。

    Java语言规定标识符由任意顺序的字母、下划线(_)、美元符号($)和数字组成,并且第一个字符不能是数字。标识符不能是Java中的保留关键字。

    下面是合法标识符:

    name

    user_age

    $page

    下面是非法标识符:

    4word

    String

    User name

    Java语言使用Unicode标准字符集,最多可以标识65535个字符,因此,Java语言中的字母不仅包括通常的拉丁文字a、b、c等,还包括汉字、日文以及其他许多语言中的文字。

    注意:在Java语言中标识符中的字母是严格区分大小写的。如good和Good是不同的两个标识符。

    (2).关键字

    关键字是Java语言中已经被赋予特定意义的一些单词。不可以把这些字作为标识符来使用。数据类型中提到的int、boolean等都是关键字,Java中的关键字如表所示:

    2、 定义变量

          变量可以理解为日常生活中的一个容器,例如箱子,它可以装衣服、金银首饰、图书、旅行用品等,关键时刻还可以藏人,总之变量的内容是可以改变的。变量的使用是程序设计中一个十分重要的环节,经常被使用,例如,如图所示。

    为什么要定义变量呢?简单的说,就是要告诉编译器(compiler)这个变量是属于哪一种数据类型,这样编译器才知道需要配置多少空间给它,以及它能存放什么样的数据。在程序运行过程中,空间内的值是变化的,所以称为变量。为了便于操作,给这个空间取个名字,称为变量名,内存空间内的值就是变量值。

    变量的命名必须是合法的标识符。在声明变量时可以不为其赋值,也可以直接赋初值。

    例 声明变量,实例代码如下:

    int age;                                          //声明int型变量

    char char1 = 'r';                        //声明char型变量并赋值

    编写以上程序代码,究竟会产生什么样的作用呢?要了解这个问题,就需要对变量的内存配置有一定的认识。用图解的方式,将上例程序代码在内存中的状况表现出来。

    系统的内存可大略的分为3个区域:系统区(OS)、程序区(Program)、数据区(Data)。当程序执行时,程序代码会加载到内存中的程序区,数据暂时存储在数据区中。假设上述两个变量定义在方法体中,则程序加载到程序区中。当执行此行程序代码时,会在数据区配置空间给这两个变量

    对于变量的命名并不是任意的,应遵循以下几条规则。

    1、变量名必须是一个有效的标识符。

    2、变量名不可以使用Java中的关键字。

    3、变量名不能重复。

    4、应选择有意义的单词作为变量名。

    说明:在Java语言中允许使用汉字或其他语言文字作为变量名。如“int 年龄 = 21”,在程序运行时并不出现什么错误,但建议读者尽量不要使用这些语言文字作为变量名。

    3、申明常量

        在程序运行过程中一直不会改变的量称为常量(constant),通常也被称为“final变量”。常量在整个程序中只能被赋值一次。在为所有对象共享值时,常量是非常有用的。

    在Java语言中声明一个常量,除了要指定数据类型外,还需要通过final关键字进行限定。声明常量的标准语法为:

    final 数据类型 常量名称[=值]

    说明:常量名通常使用大写字母,这也符合Java编码规范,但这并不是必须的,声明常量时,完全可以和变量名一样使用小写字母。但是,那样容易造成混淆,降低代码可读性,所以才有规范要求常量名全部大写,并使用“_”下划线字符分割多个单词。

    例 声明常量,实例代码如下:

    final double PI = 3.1415926D;    //声明double型常量PI并赋值

    final boolean BOOL = true;       //声明boolean型常量BOOL并赋值

    当定义的final变量属于“成员变量”,则必须在定义的时候就设定它的初值。否则将会有编译错误。下面的实例可看出变量与常量的区别。

    例 在项目中创建类Part,在类体中创建变量age与常量PI。在主方法中分别将变量与常量赋值,通过输出信息可测试变量与常量的有效范围。

     1 public class Part {   //新建类Part
     2 
     3     static final double PI = 3.14;   //声明常量PI,此时PI如不对其进行赋值,则会出现错误提示
     7     static int age = 23;     //声明int型变量age,并进行赋值
     8 
     9     public static void main(String[] args) {   //主方法
    11          final int number;     //声明int型常量number
    12          number = 1235;   //对常量进行赋值
    15          age = 22;      //再次对变量进行赋值
    16          //number = 1236;                                                                                                                        //错误的代码,因为number为常量,只能进行一次赋值
    18          System.out.println("常量PI的值为:" + PI);            //将PI的值输出
    20          System.out.println("赋值后number的值为:" + number); //将number的值输出
    22          System.out.println("int型变量age的值为:" + age);            //将age的值输出
    25     }
    27 }

    运行结果如图所示。

    4、变量的有效范围

           由于变量被定义出来后,只是暂存在内存中,等到程序执行到某一个点后,该变量会被释放掉,也就是说变量有它的生命周期。因此变量的有效范围是指程序代码能够访问该变量的区域,若超出该区域访问变量则编译时会出现错误。在程序中,一般会根据变量的有效范围,将变量分为“成员变量”和“局部变量”。

    (1).成员变量

    在类体中所定义的变量被称为成员变量。成员变量在整个类中都有效,所以成员变量也称作全局变量。

    成员变量的有效范围是整个类的代码段,也就是在类体中的任何位置都可以使用该变量。

    例 声明成员变量,并在不同方法中为成员变量赋值,代码如下:

     1 public class Temp {
     3       int num=0;
     5       float price=3.50f;
     7       public void method1(){      // 方法1访问变量num和price
     9             num=1;
    11             price=12.55f;
    13       }
    14 
    15       public void method2(){      // 方法2也可以访问变量num和price
    17             num=num*10;
    19             price=price*0.5f;
    21       }
    23 }

    类的成员变量又可分为静态变量和实例变量两种。

    (1)、静态变量

    静态变量的有效范围是整个类,并且可以被类的所有实例共享。可通过“类名.静态变量名”的方式来访问静态变量。静态变量的生命周期取决于类的生命周期,当类被加载时,为类中的静态变量分配内存空间,当卸载类时,释放静态变量占用的空间,静态变量被销毁。类加载时,就为静态变量分配内存空间,之后无论创建了多少类的实例,都不会再为静态变量分配内存空间,这些实例会使用同一个静态变量。

    (2)、实例变量

    实例变量与类的实例对应,它的有效范围是整个实例。每创建一个类的实例,都会为当前实例分配实例变量的内存空间。所以实例变量的生命周期取决于实例的生命周期,实例被创建时,为实例变量分配内存空间,当销毁实例时,释放实例变量占用的内存空间。

    例 声明静态变量和实例变量,实例代码如下:

    public class Temp {
          int x = 45;                        //定义实例变量
          static int y = 90;      //定义静态变量
    }
    

      

    2.局部变量

    在方法体中定义的变量就是一种局部变量,局部变量只在当前代码块(即花括号之内)中有效。局部变量的生命周期取决于声明位置的代码块,超出这个代码块的范围就不能在使用代码块内的局部变量。

    就拿方法类说,方法内声明的变量、包括参数变量都属于局部变量,当方法被调用时,Java虚拟机为方法中的局部变量分配内存空间,当该方法的调用结束后,则会释放方法中局部变量占用的内存空间,局部变量也将会销毁,然后Java的垃圾回收机制会在某一时刻清理该内存空间。

    变量的有效范围如图所示:

    说明:局部变量可与全局变量的名字相同,此时全局变量将被隐藏,但是可以使用“this.”做前缀来访问全局变量。

    例 在项目中创建类ValClass,分别定义名称相同的局部变量与成员变量,当名称相同时成员变量将被隐藏。

    1 public class ValClass{    //新建类
    2        static String words = "成员变量";  //定义成员变量words
    3 
    4        public static void main(String[] args) {  //主方法
    5               String words = "局部变量";     //定义局部变量words
    6               System.out.println("words变量现在是:" + words);             //将words的值输出
    7        }
    8 }

    运行结果如图所示。

    二、运算符

    1、赋值运算符

    赋值运算符是以符号“=”表示,它是一个二元运算符(对两个操作数作处理),其功能是将右方操作数所含的值赋值给左方的操作数。其语法格式如下:

    变量 = 表达式;

    例如:

    int a = 100;

    该表达式是将100赋值给变量a。左方的操作数必须是一个变量,而右边的操作数则可以是任何表达式,包括变量(如a、number)、常量(如123、'book')、有效的表达式(如45*12)。例如:

    例 使用赋值运算符为变量赋值,实例代码如下:

    int a = 10;       //声明int型变量a
    int b = 5;       //声明int型变量b
    int c = a+b;   //将变量a与b进行运算后的结果赋值给c

    遵循赋值运算符的运算规则,可知系统将先计算a+b的值,结果为15。然后将15赋值给变量c。因此“c=15”。

    说明:由于赋值运算符“=”处理时会先取得右方表达式处理后的结果,因此一个表达式中若含有两个以上的“=”运算符时,会从最右方“=”开始处理。

    例 在项目中创建类Eval,在主方法中定义变量,使用赋值运算符为变量赋值。

     1 public class Eval {    //创建类
     2      public static void main(String[] args) {  //主方法
     3          int a, b, c;      //声明int行变量a,b,c
     5          a = 15;     //将15赋值给变量a
     7          c = b = a + 4;   //将a与4的和赋值给变量b,然后再赋值给变量c
     9          System.out.println("c值为:" + c);  //将变量c的值输出
    11          System.out.println("b值为:" + b);  //将变量b的值输出
    13     }
    16 }

    运行结果如图所示。

    说明:在Java里可以把赋值运算符连在一起使用。如:

    x = y = z = 5;

    在这个语句中,变量x、y、z 都得到同样的值5,在程序开发中不建议使用这种赋值语法。

    再例如,在下面的a=a+10表达式中,先计算表达式a+10,结果为19,然后执行表达式a=19。

    int a=9;

    a=a+10;

    System.out.println(a);

    在Java中,类似a=a+10这样的表达式还可写为以下形式:

    a+=10;

    其中,+=称为复合赋值运算符,类似的复值运算符还有-=、*=、/=、%=、&=、|=和^=等。对于这些运算符的具体应用如表所示。

    说明:赋值运算符的左边必须为变量,不能为任何表达式。

    2、算数运算符

    Java中的算术运算符主要有+(加号)、—(减号)、*(乘号)、/(除号)、%(求余),它们都是二元运算符。Java中算术运算符的功能及使用方式如表所示。

    其中“+”和“-”运算符还可以作为数据的正负符号,例如+5,-7。

    下面通过一个小程序来介绍使用算术运算符的方法。

    例 在项目中创建类Arith,在主方法中定义变量,使用算术运算符将变量的计算结果输出。

     1 public class Arith {     //创建类
     2 
     3     public static void main(String[] args) { //主方法
     4          float number1 = 45.56f;  //声明float型变量并赋值
     6          int number2 = 152;    //声明int型变量并赋值
     8          System.out.println("和为:" + number1 + number2);  //将变量相加之和输出
    10          System.out.println("差为:" + (number2 - number1));  //将变量相减之差输出
    12          System.out.println("积为:" + number1 * number2); //将变量相乘的积输出
    14          System.out.println("商为:" + number1 / number2); //将变量相除的商输出
    16     }
    19 }

    运行结果如图所示。

    在应用算术运算符时,可以分为对整型数据的运算和对浮点型数据的运算,下面进行详细介绍。

    1.整型数据的算术运算

    整型数据的“+”、“-”、“*”、的运算与数学中的运算相同,这里不再介绍,下面介绍整型数据间的“/”和“%”运算。

    (1)整数的除法(运算符“/”)运算

    当整数间进行除法运算时,其结果将舍弃小数部分,并且忽略四舍五入,最终的结果为商的整数部分,所以通过计算机来计算“5/3*3”与“5*3/3”的结果是不同的,前者为3,而后者为5。

    例 在项目中创建类Arith1,在主方法中定义变量,使用“/”运算符进行除法运算,并输出计算结果。

     1 public class Arith1 {
     2 
     3     public static void main(String[] args) {  // 主方法
     4          int i1 = 7 / 3;  // 在数学计算中其结果约为2.33
     6          int i2 = 11 / 3;  // 在数学计算中其结果约为3.67
     8          int i3 = -7 / 2;  // 在数学计算中其结果为-3.5
    10          int i4 = 0 / 9;
    12          System.out.println("7/3=" + i1); // 输出结果为:2
    14          System.out.println("11/3=" + i2);  // 输出结果为:3
    16          System.out.println("-7/2=" + i3);  // 输出结果为:-3
    18          System.out.println("0/9=" + i4);  // 输出结果为:0
    21     }
    23 }

    运行结果如图所示。

    (2)整数的求余(运算符“%”)运算

    当整数间进行求余运算时,其运算结果为整数除法运算后的余数。

    例 在项目中创建类Arith2,在主方法中定义变量,使用“%”运算符进行求余运算,并输出计算结果。

    public class Arith2 {
    
         public static void main(String[] args) {   // 主方法
    int i1=11%4;  //结果为:3
    int i2=8%4;   //结果为:0
    int i3=9%10;  //结果为:9
    int i4=-7%3;  //结果为:-1
    int i5=0%9;   //结果为:0
              System.out.println("11%4="+i1);
              System.out.println("8%4="+i2);
              System.out.println("9%10="+i3);
              System.out.println("-7%3="+i4);
              System.out.println("0%9="+i5);
          }
    }

    运行结果如图所示。

    3、自增和自减运算符

            自增、自减运算符是单目运算符,可以放在操作元之前,也可以放在操作元之后。操作元必须是一个整型或浮点型变量。自增、自减运算符的作用是使变量的值增1或减1。放在操作元前面的自增、自减运算符,会先将变量的值加1(减1),然后再使该变量参与表达式的运算。放在操作元后面的自增、自减运算符,会先使变量参与表达式的运算,然后再将该变量加1(减1)。

    例 应用两种自增运算符的输出结果。下面的代码:

    int i=1;
    System.out.println("使用i++的结果:");
    System.out.println(i++);
    System.out.println(i);
    i=1;
    System.out.println("使用++i的结果:");                       
    System.out.println(++i);
    System.out.println(i);     
    

      运行结果如图所示。

    下面我们通过图来看一看i++与++i的区别。

    例 应用两种自减运算符的输出结果。下面的代码:

    int i=1;
    System.out.println("使用i--的结果:");
    System.out.println(i--);
    System.out.println(i);
    i=1;
    System.out.println("使用--i的结果:");                       
    System.out.println(--i);
    System.out.println(i);     

    运行结果如图所示。

    注意:自动递增、递减运算符的操作元只能为变量,不能为字面常数和表达式,且该变量类型必须为整型、浮点型或Java包装类型。例如:++1、(num+2)++都是不合法的。

    4、比较运算符

            比较运算符属于二元运算符,用于程序里的变量之间、变量和自变量之间以及其他类型的信息之间的比较上。比较运算符的运算结果是boolean型。当运算符对应的关系成立时,运算结果是true,否则是false。所有比较运算符通常用在条件语句中作为判断的依据。比较运算符共有6个,如表所示

    运算符

    作用

    举例

    操作数据

    结果

    >

    比较左方是否大于右方

    'a'>'b'

    整型、浮点型、字符型

    false

    <

    比较左方是否小于右方

    156 < 456

    整型、浮点型、字符型

    false

    ==

    比较左方是否等于右方

    'c'=='c'

    基本数据类型、引用型

    true

    >=

    比较左方是否大于等于右方

    479>=426

    整型、浮点型、字符型

    True

    <=

    比较左方是否小于等于右方

    12.45<=45.5

    整型、浮点型、字符型

    true

    !=

    比较左方是否不等于右方

    'y'!='t'

    基本数据类型、引用型

    true

    注意:相等“==”运算符和“=”赋值运算符要严格区分,不要混淆,如果在条件判断语句中,把“==”写成“=”会导致错误发生。这是初学者最容易犯错的地方,可以把常量放置“==”的左面,右面放变量或其它。例如if(3 == x),这也是一些程序开发人员的惯用写法,这样做,“==”错写为“=”时,编译器会报告错误。

    例 在项目中创建类Compare,在主方法中创建整型变量,使用比较运算符对变量进行比较运算,将运算后的结果输出。

    public class Compare {    //创建类
    
        public static void main(String[] args) {
    int number1 = 4;   //声明int型变量number1
             int number2 = 5;   //声明int型变量number2
             System.out.println("number1 > number2的返回值为:" + (number1 > number2));
             /*依次将变量number1与变量number2的比较结果输出*/
             System.out.println("number1 < number2的返回值为:" + (number1 < number2));
             System.out.println("number1 == number2的返回值为:" + (number1 == number2));
             System.out.println("number1 != number2的返回值为:" + (number1 != number2));
             System.out.println("number1 >= number2的返回值为:" + (number1 >= number2));
             System.out.println("number1 <= number2的返回值为:" + (number1 <= number2));
         }
    }

    5、逻辑运算符

              返回类型为布尔值的表达式,比如比较运算符。可以被组合在一起构成一个更复杂的表达式。这是通过逻辑运算符来实现的。逻辑运算符包括&(&&)逻辑与、||(逻辑或)、!(逻辑非)。逻辑运算符的操作元必须是boolean型数据。在逻辑运算符中,除了“!”是一元运算符之外,其他都是二元运算符。表给出逻辑运算符的用法和含义。

    运算符

    含义

    用法

    结合方向

    &&、&

    逻辑与

    op1&&op2

    左到右

    ||

    逻辑或

    op1||op2

    左到右

    逻辑非

    !op

    右到左

    结果为boolean型的变量或表达式可以通过逻辑运算符组合为逻辑表达式。

    用逻辑运算符进行逻辑运算时,结果如表所示。

    表达式1

    表达式2

    表达式1&&表达式2

    表达式1||表达式2

    !表达式1

    true

    true

    true

    true

    false

    true

    false

    false

    true

    False

    false

    false

    false

    false

    True

    false

    true

    false

    true

    true

    逻辑运算符“&&”和“&”都是表示逻辑与,那么他们之间的区别在哪里呢?从表可以看出当两个表达式都为true时,逻辑与的结果才会是true。使用逻辑运算符“&”会判断两个表达式。而逻辑运算符“&&”则是针对boolean类型类进行判断,当第一个表达式为false时,则不去判断第二个表达式,直接输出结果。使用“&&”可节省计算机判断的次数。通常将这种在逻辑表达式中从左端的表达式可推断出整个表达式的值称为“短路”。而那些始终执行逻辑运算符两边的表达式称为“非短路”。“&&”属于“短路”运算符,而“&”则属于“非短路”运算符。

    例 在项目中创建类Calculation,在主方法中创建整型变量,使用逻辑运算符对变量进行运算,将运算结果输出。

    public class Calculation {      //创建类
    
         public static void main(String[] args) {
    int a = 2;    //声明int型变量a
    int b = 5;    //声明int型变量b
             boolean result = ((a > b) && (a != b));  //逻辑与&&运算
    boolean result2 = ((a > b) || (a != b));  //逻辑或||运算
             System.out.println("(2 > 5) && (2 != 5) = "+result);   //变量result输出
             System.out.println("(2 > 5) || (2 != 5) = "+result2); //变量result2输出
             System.out.println("!(5 > 2) = " +!(5 > 2));  //逻辑非!运算
          }
    }

    6、位运算符

     位运算符用于处理整形和字符型的操作数。位运算是完全针对二进制位(bit)单位的操作。Java语言提供的位运算符如表所示。

    运算符

    用法

    含义

    运算分类

    ~ 非

    ~op1

    对op1操作数按位取反

    按位运算

    & 与

    op1 & op2

    op1和op2按位相与

    | 或

    op1 | op2

    op1和op2按位相或

    ^ 异或

    op1 ^ op2

    op1和op2按位异或

    << 左移位

    op1 << op2

    op1按位左移op2次

    移位运算符

    >> 右移位

    op1 >> op2

    op2按位右移op2次

    >>> 无符号右移位

    op1 >>> op2

    op2不带符号按位右移op2次

    说明:Java的位运算符中,“~”非运算是一元运算符,除此之外的都是二元运算符。

    1.“按位与”运算

    “按位与”运算的运算符为“&”,&是二元运算符。“按位与”运算的运算法则是:如果两个整型数据a、b对应位都是1,则该位结果才是1,否则为0。即

    0&0=0                        0&1=0                        1&0=0                        1&1=1

    例如:153的二进制是10011001,46的二进制是00101110,这两个数按位与运算的方法如下,括号中的是十进制数。

    10011001(153)

    &            00101110(46)

    ---------------------------------

                00001000(8)

    2.“按位或”运算

    “按位或”运算的运算符为“|”,它是二元运算符。“按位或”运算的运算法则是:如果两个操作数对应位都是0,则该位的结果才是0,否则为1。即

    0|0=0                        0|1=1                        1|0=1                        1|1=1

    例如:153的二进制是10011001,46的二进制是00101110,这两个数按位进行或运算的方法如下,括号中的是十进制数。

    10011001(153)

    |            00101110(46)

    ---------------------------------

                10111111            (191)

    3.“按位取反”运算

    “按位取反”运算也称“按位非”运算,运算符为“~”,~为一元运算符。它的运算法则是操作数二进制中的1修改为0,0修改为1。即

    ~0=1                        ~1=0

    例如:153的二进制是10011001,把它按位取反的结果为01100110

    4.“按位异或”运算

    “按位异或”运算的运算符位“^”,^为二元运算符。“按位异或”运算的运算法则是:当两个操作数的二进制对应位相同(同时为0或同时为1)时,结果为0,否则为1。即

    0^0=0                        0^1=1                        1^0=1                        1^1=0

    例如:153的二进制是10011001,46的二进制是00101110,这两个数按位进行异或运算的方法如下,括号中的是十进制数。

    10011001(153)

    ^            00101110(46)

    ---------------------------------

                10110111(183)

    5.位移运算

    除了上述按位运算符之外,还可以对数据按二进制位进行移位操作,Java中的移位运算符有三种:

    q << 左移

    q >> 右移

    q >>> 无符号右移

    左移就是将左边的操作数在内存中的二进制数据左移右边操作数指定的位数,左边移空的部分补0。右移则复杂一些。当使用“>>”符号时,如果最高位是0,左移空的位就填入0;如果最高位是1,右移空的位就填入1。如图所示。

    Java还提供了无符号右移“>>>”,不管最高位是0还是1,左移空的高位都添入0。

    注意:移位运算符适用的数据类型有byte、short、char、int、long。

    技巧:移位能让我们实现整数除以或乘以2的n次方的效果,如:y<<2于y*4的结果相同;y>>1的结果于y/2的结果相同。总之,一个数左移n位,就是将这个数乘以2的n次方,一个数右移n位,就是将这个数除以2的n次方。

    7、三元运算符

        三元运算符使用格式为:

    条件式?值1:值2

    三元运算符的运算规则为:若条件式的值为true,则整个表达式取值1,否则取值2。例如:

    int x = 1;
    int y = 2;
    int num = x < y ? 10 : 20;  

    如上例所示,当表达式“x < y”的运算结果返回true时,则变量num取值10,当表达式“x < y”返回false时,则变量num取值20。上例的结果为num等于10。

    例 使用三元运算符求两数中的最大数。

    public class ComputeMax {
    
         public static void main(String[] args) {
             int x=32;  // 声明变量x
    int y=23;  // 声明变量y
    int max=x>y?x:y;  // 声明变量max并赋值x与y的最大数
             System.out.println("x="+x); //输出x的值
             System.out.println("y="+y); //输出y的值                       
             System.out.println("x、y两数中最大的值为:"+max);
         }
    }

    8、运算符优先级

         Java中的表达式就是使用运算符连接起来的符合Java规则的式子。运算符的优先级决定了表达式中运算执行的先后顺序。通常优先级由高到低的顺序依次是:

    (1) 增量和减量运算

    (2) 算术运算

    (3)比较运算

    (4) 逻辑运算

    (5)赋值运算

    如果两个运算有相同的优先级,那么在左边的表达式要比在右边的表达式先被处理。表显示了在Java里众多运算符的特定的优先级。

    优先级

    描述

    运算符

    括号

    ( )

    正负号

    + -

    一元运算符

    ++ -- !

    乘除

    * / %

    加减

    + -

    移位运算

    << >> >>>

    比较大小

    < > >= <=

    比较是否相等

    == !=

    按位与运算

    &

    按位异或运算

    ^

    按位或运算

    |

    逻辑与运算

    &&

    逻辑或运算

    ||

    三元运算符

    ?:

    赋值运算符

    = += -= *= /= %=

    技巧:在编写程序时尽量使用括号()运算符号来限定运算次序,以免产生错误的运算顺序。

    三、数据类型转换

    1、自动类型转化

            Java的8个基本数据类型可以进行混合运算。不同类型的数据在运算过程中,首先会自动转换为同一类型,然后才进行运算。数据类型可以根据占用存储空间大小分为高低级别,占用空间越小,级别越低,占用空间越大,级别越高。自动类型转换遵循低级到高级转换的规则。如图所示。从左到右的数据类型不断升高,箭头指明了自动类型转换的规则。

    基本数据类型的自动类型转换会发生在以下几种情况:

    (1)变量赋值

    当为变量赋值的数据类型与变量类型不一致,并且赋值的数据类型级别低于变量类型的级别时,自动数据类型转换会将赋值数据自动转换为变量的类型。

    例如:

    byte byteNum=23;    // 声明byte类型变量
    int intNum=byteNum;    // 把byte型数据赋值给int型变量

    (2)方法调用

    把一个数值传递给方法的参数,并且这个数值的数据类型低于方法的参数变量的数据类型。

    例如:

    public static void say(int num){
        System.out.println("这是int类型数值:"+num);
    }
    
    public static void main(String[] args) {
    byte byteNum=23;
        say(byteNum);    // 把byte数值传递给方法的int参数
    }

    一元运算

    在一元运算中(除了++和—运算符),如果操作数的类型低于int类型(即byte、short和char类型),则操作数会自动转换为int类型。

    二元运算符

    在二元运算中,所有低级的数据类型都会转换为运算中级别最高的数据类型。也就是说,如果有一个操作数是double类型,其他操作数都会自动转换为double类型。如果运算中最高的数据类型是float,其他操作数都会转换为float类型。如果最高的数据类型为long,那么所有操作数都会自动转换为long类型。如果最高的数据类型为int那么所有操作数都会自动转换成int类型。至于byte、short、char类型会自动转换为int或运算中最高的数据类型。

    例 在项目中创建类Conversion,在主方法中创建不同数值型的变量,实现将各变量的自动类型转换。

    public class Conversion {
    public static void main(String[] args) {
            byte b1=34;
    short s1=123;
            char c1='B';
    int i1=40;
    long l1=900L;
            float f1=8.11F;
    double d1=3.1415926;
            System.out.println("double/byte+char->double	"+(d1/b1+c1));
            System.out.println("long+short->long		"+(l1+s1));
            System.out.println("char+byte+short->int		"+(c1+b1+s1));
            System.out.println("float+b1/s1->float		"+(f1+b1/s1));
            System.out.println("int+double->double		"+(i1+d1));
       }
    }

    运行的结果如图所示:

    技巧:要理解类型转换,大家可以这么想象,大脑前面是一片内存,源和目标分别是两个大小不同的内存块(由变量及数据的类型来决定),将源数据赋值给目标内存的过程,就是用目标内存块去套取源内存中的数据,能套多少算多少。

    2、强制类型转换

     当把高级别(即占用存储空间较大)的数据类型赋值给低级别(即占用存储空间较小)的数据类型时,必须进行的强制类型转换。其语法格式如下:

    (类型)(表达式)

    类型是要转换成的目标类型,例如int、short、double等。表达式是要转换的目标数据,它可以是任何基本类型的算术运算表达式。

    例如:

    long num=900L;      // 900
    short snum=(short)num;  // 900

    long类型的数值900没有超过short类型的取值范围,所以short类型的变量“snum”完全容纳了强制类型转换后的数值。

    基本数据类型的强制类型转换需要注意数据完整性的问题,当把高级的数据类型强制转换为低级的数据类型时,如果数值超出低级数据类型的取值范围,数值将被截取,导致数据丢失、不完整。

    例如:

    short snum=516;       // 516
    byte bnum=(byte)snum;  // 4

    snum是short类型,数据长度是16位,而bnum是byte类型,长度为8位。当snum强制转换为byte类型时,数值“516”超出了byte类型的取值范围,这是只能从short类型截取低8为的数据赋值给byte类型的bnum变量。如图所示。

    这样就造成了数据丢失,所以在使用强制数据类型转换时,一定要倍加小心。

    注意:boolean布尔型的数值不能被牵制类型转换为其他数据类型,反之亦然。

    例 将long类型数值强制类型转换为其他数据类型

    public class PConversion {
    
        public static void main(String[] args) {
    long num=33333;
            System.out.println("原数是:"+num);
            System.out.println("转成int:"+(int)num);
            System.out.println("转成short:"+(short)num);
            System.out.println("转成byte:"+(byte)num);
            System.out.println("转成float:"+(float)num);
            System.out.println("转成char:"+(char)num);
        }
    }

    实例运行结果如图所示。

  • 相关阅读:
    EF-CodeFirst-3搞事
    EF-CodeFirst-1 玩起来
    EF-CodeFirst-2玩的嗨
    Asp.Net SignalR Hub类中的操作详解
    Asp.Net SignalR GlobalHost外部通知
    Asp.Net SignalR 多平台的Client与Server
    Asp.Net SignalR 集群会遇到的问题
    常用数学符号读法大全
    关于神经网络拟合任意函数的讨论
    Asp.net MVC使用FormsAuthentication,MVC和WEB API可以共享身份认证 (转载)
  • 原文地址:https://www.cnblogs.com/dnn179/p/10857362.html
Copyright © 2020-2023  润新知