《疯狂Java讲义》第3章——数据类型和运算符

来源:互联网 发布:基于java博客 编辑:程序博客网 时间:2024/04/30 14:33

本章讲述的内容可以分为注释、数据内容、运算符三大块,文章结构大致如下图所示:

  • 注释
    • 单行、多行注释
    • 文档注释以及javadoc命令
  • 数据类型

    • 基本数据类型
      • 分类
        • 整形(byte、short、int、long)
        • 字符型(char)
        • 浮点型(float)
        • 布尔型(boolean)
      • 类型转换
        • 自动类型转换
        • 强制类型转换
  • 运算符

    • 算数运算符(+、-、*、/、%、++、–)
    • 赋值运算符(=)
    • 位运算符(&、|、~、^、<<、>>、>>>)
    • 比较运算符(>、>=、<、<=、==、!=)
    • 逻辑运算符(&&、&、||、|、!、^)
    • 三目运算符(? :)

首先,先来看第一部分——注释:

一、注释

        注释是给人看的,因此不会被计算机所识别和执行,根据不同的需要,分类如下:

        1)单行注释和多行注释:

        不多讲,看下面片段:

public class CommentTest{        /*            这里面的内容都是多行注释的内容,            不会被执行        */    public static void main(String[] args){        //这是单行注释        System.out.println("Hello world!");        //System.out.println("这行代码被注释了,不会被执行");    }}

        2)文档注释:

                Java基础类库中有成千上万的类,开发者不可能全部记住它们,那么就需要有一份说明性的文档,把这些类,以及类中方法的用途记录下来,以便查阅。对于Java 8 ,可以在Oracle官网下载页,将滚动条滚动到下方,如图:

这里写图片描述

下载到Java 8的API说明文档。下载成功后会得到一个jdk-8u65-docs-all.zip文件,将它解压后,会得到一个jdk-8u65-docs-all文件夹,在文件夹下的docs/api目录下,打开index.html,就可以看到Java 8 的API说明文档,如下图所示:

这里写图片描述

这是打开index.html后,访问到的Java 8 API文档首页:

这里写图片描述

                说了这么多,跟文档注释有什么关系呢?其实,如此庞大的Java API说明文档,就是文档注释+javadoc的杰作!这里先说说文档注释。文档注释,顾名思义,就是”用来生成API文档的注释“,例如:

public class DocCommentTest{    private String comment;    /**    * 这里是文档注释,用于生成可阅读的文档    */    public String getComment(){        return comment;    }}

                由上面的代码片段可见,所谓文档注释,在格式上,只是比多行注释在开头处多了一个星号

                那么,仅仅因为多了一个星号,就多出了一种注释的方式吗?不是的,文档注释还要配合javadoc工具,才能体现出它的价值来。那么javadoc又是干什么的呢?javadoc和javac、java一样,是一个exe文件,它的功能是识别java源文件中的文档注释,并按照一定规则将文档注释提取出来,生成一份可读性好的API文档。语言是苍白的,下面做一个小例子来加以说明:

首先,写两个类:

package lee;public class JavaDocTest{    /**     * 简单测试成员变量     */     protected String name;     /**      * main方法      */     public static void main(String[] args){            System.out.println("Hello world!");     }}
package yeeku;public class Test{    /**    * 简单测试成员变量    */    public int age;    /**    * Test类的测试构造器    */    public Test(){}}

备注:上面的两个类分别在JavaDocTest.java文件和Test.java文件中,在cmd命令行输入命令,如下所示:

这里写图片描述

执行命令后,源文件父目录下多出了一个apidoc文件夹,如图所示:

这里写图片描述

进入apidoc文件夹中,如图所示:

这里写图片描述

打开Index.html文件,可以看到,两个java源文件中的类的文档注释,已经被成功提取成为一份API文档,下图中标示了javadoc命令各项参数的效果:

这里写图片描述

在左下角区域选择Test类,可以看到,在Test.java中为Test类的成员变量age,以及为Test的构造器所做的文档注释,如下图所示:

这里写图片描述

注释的内容就介绍到这里。

二、数据类型

        1)基本数据类型:

        1.分类:

        a)整形:

        各种整型的表示范围如下表:

类型 位数 字节数 大小 最高位 byte 8 1 -2^7 ~ 2^7 - 1 符号位 short 16 2 -2^15 ~ 2^15 - 1 符号位 int 32 4 -2^31 ~ 2^31 - 1 符号位 long 64 8 -2^63 ~ 2^63 - 1 符号位


        其中,int是最常用的类型。

        对于整型系列,有几点比较特殊的地方:

        1、对于一个在byte类型范围的整型值,可以直接赋给byte类型的变量:

public static void main(String[] args){    //允许,虽然23默认是int类型,但因为其值比较小,    //赋给byte类型变量bValue时,把它当成byte类型    byte bValue = 23;//在byte范围内,正常    byte bValue1 = 1213;//超出byte范围,错误    //同样地,以二进制数表示的整型,如果是在byte范围内,    //也可以直接复制给byte变量    byte binValue = 0b01101001;//在byte范围内,正常    byte binValue1 = 0b11101111;//超出byte范围,错误}

        2、对于一个超过了int类型范围的整型值,不可以赋给long类型的变量:

public static void main(String[] args){    //下面代码错误,系统不会把99999999999999当成long类型,    //而会认为99999999999999超出了int类型最大表示范围,    //从而报错    long bigValue = 99999999999999;    //为了使得上面的赋值操作可以实现,需要将int类型升级为long类型    //通过在数值后加上一个"L",指明该数值是long类型直接量    long bigValue1 = 99999999999999L;}

        3、整型值的4种表示方式:

        a)十进制:十进制想必没有什么好说的了,大家日常每天都在用

        b)二进制:

                以0B开头,每一位可取的值只有0、1,例如:

public static void main(String[] args){    //定义2个8位的二进制整数    int binVal1 = 0b11010100;    int binVal2 = 0b01101001;    System.out.println("binVal1:" + binVal1);//212    System.out.println("binVal2:" + binVal2);//105}

        下面我们来计算一下binVal1和binVal2是不是分别等于212和105:

        首先,计算binVal1(0b11010100):

                      1.最高位是符号位,是1,所以binVal1是一个负数

                      2.将剩下的数值位转化为十进制数,得到84

                      3.于是binVal1 = -84

                咦?怎么不是212,不但数值不对,正负号都搞错了!!!

                这里涉及到几个问题:

                      q1:哪一位是最高位?是左手边数起第一位吗?如果不是,那是哪一位?

                      q2:我们人看到的实际数字,和计算机保存的数字是同一个数字吗?

                我们可以注意到,binVal1的类型是int,那么意味着它的位数是32位,而我们赋给binVal1的数值是一个8位的整数,那这时系统发现位数不够,于是把它前面的32 - 8 = 24个位都补上0,此时

                      binVal1=0b00000000000000000000000011010100

                此时再看,binVal1最高位已经变成0,再将其他位作为数值位,进行转换,得到数值——212

                这回终于对了!前面提出的问题q1可以回答了——要看变量的类型来具体判定最高位是哪一位同个道理,binVal2的值也可以计算得出。但是,问题q2怎么好像没有体现到?且看下面这段程序:

public static void main(String[] args){    //定义32位二进制整数    int binVal3 = 0b10000000000000000000000000000011;     System.out.println("binVal3:" + binVal3);//-2147483645}

                嘿嘿,这回binVal3的值正好是32位的,我们发现最高位是1,数值位是3,结果想当然的是-3,但是真正的结果是-2147483645,这回真的是差了十万八千里了!

                怎么回事呢?原来,正如上面的q2问题,答案是否定的——计算机中存的数,其实跟我们看到的数不是同一回事,计算机是把所有的数都转换成补码存了起来,而当被读取的时候,又把补码转换为原码,呈现在人们面前。那么问题来了——什么是原码?补码又是什么?

                原码是计算机为了在系统中表示正负号,在原来的数字的数值部分的前面,增加一位作为符号位,形成的新数。例如:-8要存进计算机里,就要转换成二进制的表示,数值部分的8好转,直接就是1000,那负号怎么办呢?计算机只认识0和1呀!于是原码来了——在数值位前面增加1位作为符号位,于是-8就是11000,可是Java中没有5位的整型类型呀,那么我们就假设这个-8是个byte类型的吧,byte是8位,那么它的符号位1就应该在左手边第一位,所以十进制的-8转换成二进制byte型就应该是10001000——这就是-8的原码。

                现在计算机认识-8了,可是为什么又有一个补码的概念呢?简单的来说,补码是为了计算机更方便地进行运算——在运算的时候,可以将符号位视为数值位,一起参与运算,而不必担心结果出错。因此,计算机以原码到补码转换过程的开销,换取了节省计算过程中区分符号位与数值位的开销的便利

                原码转换为补码的步骤是这样子的:

                    当原码是正数时:不用转化,原码与补码相等

                    当原码是负数时:

                         1.获得反码——符号位不变,数值位取反

                         2.获得补码——反码+1

                当我们使用二进制的时候,计算机默认把二进制数当成补码,直接存到变量里面;而当我们使用十进制的时候,计算机是把十进制数当成原码,再将原码转为补码,再存入到变量中。而等到打印输出的时候,计算机又把存在变量里的补码,统统转换成原码,展现在我们面前。

                因此binVal3 = 0b10000000000000000000000000000011,这个数其实是一个补码,那么必须将它转换为原码,才是打印输出的结果。补码转换为原码的步骤与原码转为补码的步骤互逆:

          当补码是负数时:

                1.获得反码——补码 - 1(0b10000000000000000000000000000010);

                2.获得原码——符号位不变,数值位取反(0b11111111111111111111111111111101)

          当补码是正数时,补码和原码相等。

                于是,binVal3的原码是:0b11111111111111111111111111111101,转为十进制,就是-2147483645

                假如binVal3使用十进制数存进去,例如binVal3 = -3,那么计算机会将-3视为原码(而不是补码),并将它转换为补码存到内存中,当打印输出时,又会将-3从补码形式转回原码形式,于是一来一回,相当于没转,于是打印输出还是-3.

        c)八进制:

                八进制数以0打头,如下所示:

public static void main(String[] args){    //8进制数,0打头    int octalValue = 013;    System.out.println("octalValue :" + octalValue);//输出11}

        d)十六进制:

                16进制数用0x打头,如下所示:

public static void main(String[] args){    //16进制数,0x打头    int hexValue1 = 0x13;    int hexValue2 = 0xaF;    System.out.println("hexValue1 :" + hexValue1);//输出19    System.out.println("hexValue2 :" + hexValue2);//输出175}

        4、溢出:

        i)什么叫溢出:

                溢出,其实有很多种语义场景,比如说,内存溢出、缓冲溢出等等。然而,无论是什么类型的溢出,都是因为同一个原因——装不下了,那怎么办呢,硬塞呗——结果就是在这个“硬塞”的过程中,我们损失了一些东西。

                我们这里的溢出,指的是变量代表的那一块小内存,装不下我们人为地想要装进去的数值,那么我们就把这个大数进行一下强制类型转换(关于强转,本文后面会讲到),然后硬塞进去,结果出问题了——实际存进变量的值,跟我们放进去的,不是同一个数值。也就是说,原来的大数,在强转的过程当中,出现了损失,因而变成了另外一个数。

        ii)溢出举例:

public static void main(String[] args){    /*       定义1个8位二进制数,但它实际上占了32位,因此       虽然左手边起第8位是1,但它经过位数扩展之后,       仍然是一个正数0b0000_0000_0000_0000_0000_0000_1110_1001,       也就是233,但是已经超过了byte的范围,       现在要把它赋给一个byte类型的变量,必须进行强转,       强转的结果是0b1110_1001,也就是不要前面的24位,       因为现在最高位是1,是负数,将补码转为原码,得到       0b1001_0111,也就是-23,而这就产生了溢出    */    byte bValue = (byte)0b11101001;//这里的二进制数是补码    System.out.println("bValue :" + bValue);//-23}

结果:

这里写图片描述

        5、新特性:

                为了方便程序员看清位数较多的数值,在Java7之后,允许在数值中的数位之间添加分隔号”_”,例如:

public static void main(String[] args){    int iValue = 0b0000_0001_0001_1101_0010_0101_0011_1111;    double dValue1 = 3.14_15_92_63;}

        b)字符型:

              1)字符集:

                       计算机保存字符的时候,实际上是把该字符对应的编号,转化为二进制代码,保存到计算机中。因此,需要为每个字符,编上一个编号,有多少个字符,就编多少个号,形成很多个”字符<–>编号“这种一一对应的映射关系,这些映射关系,就组成了所谓的字符集。

                       例如,ASCII字符集只给英文字母、数字、标点符号编码,总共加起来不超过100个,于是ASCII字符集只用了一个字节(最多可表示256个字符)来编码。然而到了后来,随着世界各地各种语言的假如,字符越来越多,于是采用两个字节编码的Unicode字符集又应运而生了。

                       总而言之,字符集的出现,是为了解决计算机不认识人类世界的符号,又必须要保存这些符号的矛盾。

              2)表示法:

                       Java中表示单个字符,可以有以下三种形式:

                       a)直接法:直接用单引号括住字符,例如 ‘a’表示字符a

                       b)转义法:一些特殊字符,必须通过转义普通字符来表示,例如: ‘\r’表示”回车“字符, ‘\n’表示”换行“字符

                       c)Unicode法:用Unicode值来表示,形如: ‘\uXXXX’,其中 ‘XXXX’代表一个16进制的数

              3)与int类型的关系:

                            把一个int类型的值赋给一个char类型的变量,系统会认为该int值是char字符的编码,例如:char c = 97 ,当输出c的值时,会发现是字符 ‘a’

              4)示例程序:

public static void main(String[] args){        //直接指定单个字符作为字符值        char aChar = 'a';        System.out.println("aChar:" + aChar);//输出a        //使用转义字符作为字符值        char enterChar = '\n';        System.out.print("enterChar:" + enterChar);//输出一个回车符        //使用Unicode编码值来指定字符值        char ch = '\u9999';        System.out.println("ch:" + ch);//输出中文"香"字        char zhong = '疯';        System.out.println("zhong:" + zhong);//输出中文"疯"        int zhongVal = zhong;        System.out.println("zhongVal:" + zhongVal);//输出中文"疯"的unicode值        char c = 97;        System.out.println("c:" + c);//输出字符'a'    }

              结果如下所示:

这里写图片描述

        c)浮点型:

              1)分类:

                      1.float:单精度,长度32位 = 1位符号+8位指数+23位尾数

                      2.double:双精度,长度64位 = 1位符号+11位指数+52位尾数

              2)特殊值:

                      1.POSITIVE_INFINITY:正无穷

                      2.NEGATIVE_INFINITY:负无穷

                      3.NAN:非数

              3)示例程序:

public static void main(String[] args){        //下面输出的af并不精确,原因是Java使用二进制的科学计数法表示        //浮点数        float af = 5.2345556f;        System.out.println("af:" + af);        double a = 0.0;         double b = Double.NEGATIVE_INFINITY;        float d = Float.NEGATIVE_INFINITY;        //double中的负无穷和float的负无穷是相等的        System.out.println("b == d : " + (b == d));        //0.0/0.0得到非数        System.out.println("0.0 / 0,0: " + (0.0/0.0));        //非数之间不相等        System.out.println("a / a == Float.Nan : " + (a / a == Float.NaN));        //正无穷之间是相等的        System.out.println("6.0 / 0.0 == 342.0 / 0.0 : " + (6.0 / 0.0 == 342.0 / 0.0));        //下面将抛出“除数不能为0”的异常        //System.out.println(0 / 0);    }

结果如下所示:

这里写图片描述

        d)布尔型:

             布尔型只有一个boolean类型,而且取值只能是true或者false,而且不能像在C语言中一样,用非0的数代替true,用0代替false

        2.类型转换

                1)自动类型转换

                      指的是一种基本类型的值,可以直接赋给另一种基本类型的变量,而不加任何限制条件,简称“小转大”。

                      Java的自动类型转换分为以下两种:

                           1、小数值类型—>大数值类型(存在两条类型提升线路)

                                    byte–>short–>int–>long–>float–>double

                                    char–>int–>long–>float–>double

                           2、非String类型—>String类型

示例程序:

public static void main(String[] args){        int a = 6;        //int类型自动转换为float        float f = a;        //将输出6.0        System.out.println("f : " + f);        //定义byte        byte b = 9;        //byte无法自动转型为char        //char c = b;        //byte可以自动转型为double        double d = b;        //将输出9.0        System.out.println("d:" + d);        //int、float、double与String使用“+”连接时        //统统自动转化为String        String s = "Hello" + 10 + 1.3f + 3.2;        System.out.println("s : " + s);//输出Hello101.33.2    }   

                2)强制类型转换

                      指的是一种基本类型的值,不能直接赋值给另一种基本类型的变量,必须将该值的类型强制转为目标变量的类型,然后才能进行赋值操作。强制类型转换的格式形如:(TargetType)value,一般都是把类型较大的value强制转为类型较小的TargetType,简称“大转小”,容易产生溢出(关于溢出,已经在前面介绍)

示例程序:

public static void main(String[] args){        int iValue = 233;        //将int类型的值强制转换为byte,发生溢出        byte bValue = (byte)iValue;         //输出bValue        System.out.println("bValue:" + bValue);//输出-23        double dValue = 4.44;        //将double类型的值强制转换为int        int iValue2 = (int)dValue;        //输出iValue2        System.out.println("iValue2: " + iValue2);//输出4    }

                3)表达式类型自动提升

                      所谓的表达式类型自动提升,有两方面的意义:

                      1、byte、short、char,这几个类型中的一种或多种在一个表达式中出现时,该表达式最后的类型都是int

示例程序:

public static void main(String[] args){    byte bValue = 1;    short sValue = 2;    char cValue = 3;    byte bResult = bValue + bValue;    short sResult = sValue + bValue;    char cResult = cValue * cValue;}

执行效果:

这里写图片描述

可见,byte、short、char在进行运算的时候,自动提升为了int

                      2、在一个表达式中,如果有多种数据类型的变量(或常量)存在,那么该表达式中的其他变量(或常量)的类型将被提升到该表达式中最高等级操作数相同的类型,从而使整个表达式的类型与最高等级操作数的类型相同。简单地来说,就是最高类型决定了该表达式的最终类型

示例程序:

public static void main(String[] args){        //定义一个short类型的变量        short sValue = 5;        //下面语句将发生错误,因为=右边最大的数据类型是int类型,        //所以右边整体是int类型,而int类型无法自动转换为short类型        sValue = sValue - 9;        byte b = 40;        char c = 'a';        int i = 23;        double d = .231;        //=右边最高类型是double,所以应该赋给一个double类型的变量        double result = b + c + d * i;        //result的类型是double        System.out.println("result : " + result);    }

三、运算符

        1、算术运算符:

                算术运算符包括加(+)、减(-)、乘(*)、除(/)、取余(%),其中,加减乘三种运算,需要注意的是确保运算结果不超过赋值目标的类型大小。而除法和取余则需要考虑到更多的问题,见如下示例程序:

public static void main(String args){        double d1 = 5.5;        double d2 = 4.6;        double div = d1 / d2;        //输出d1 / d2的结果:1.1956521739130437        System.out.println("d1 / d2 :" + (d1 / d2));        //输出正无穷大 Infinity        System.out.println("5.0 / 0 :" + (5.0 / 0));        //输出负无穷大:-Infinity        System.out.println("-5.0 / 0 :" + (- 5.0 / 0));        //输出非数:NaN        System.out.println("0.0 / 0: " + (0.0 / 0));            //抛“除数不能为0”异常        System.out.println("5 / 0" + (5 / 0));}

效果如图:

这里写图片描述

        2、赋值运算符:赋值运算符”=”比较简单,过程就是将”=”右边的数值赋给左边的变量,此处不再解释

        3、位运算符:

                位运算符针对的对象是整型变量或直接量,可分为以下几组:

                1)&、|、^:

                         这一组分别是按位与、按位或、按位异或,操作的类型的都是整型的变量或直接量。进行操作时,将操作符两边的操作数都表示为二进制,对应的每一位按照下表的规则进行匹配运算:

操作数1 操作数2 按位与(&) 按位或(|) 按位异或(^) 0 0 0 0 0 0 1 0 1 1 1 0 0 1 1 1 1 1 1 0


示例程序:

    public static void main(String[] args){        //5的二进制表示是:0000_0000_0000_0000_0000_0000_0000_0101        //9的二进制表示是:0000_0000_0000_0000_0000_0000_0000_1001        //按位与,结果是0000_0000_0000_0000_0000_0000_0000_0001,,也就是1        System.out.println("5 & 9 :" + (5 & 9));        //按位或,结果是0000_0000_0000_0000_0000_0000_0000_1101,,也就是13        System.out.println("5 | 9 :" + (5 | 9));        //按位异或,结果是0000_0000_0000_0000_0000_0000_0000_1100,也就是12        System.out.println("5 ^ 9 :" + (5 ^ 9));    }

结果如下:

这里写图片描述

                2)~:

                         这一组只有一个操作符——按位非。为什么把它单独放在第二组呢,因为它是位操作符中唯一的一个单目运算符(即只有一个操作数的运算符),它的运算规则是:将操作数的每一位(包括符号位)进行取反操作,即遇1则0,遇0则1

示例程序:

public static void main(String[] args){    //5的二进制表示是:0000_0000_0000_0000_0000_0000_0000_0101    //-5的二进制表示是:1111_1111_1111_1111_1111_1111_1111_1011(补码)    //5取反就是:1111_1111_1111_1111_1111_1111_1111_1010(补码)    //转换成原码就是:1000_0000_0000_0000_0000_0000_0000_0110,也就是-6    System.out.println("~5 :" + (~5));    //-5取反就是:0000_0000_0000_0000_0000_0000_0000_0100(补码),也就是4(正数的补码和原码相同)    System.out.println("~-5 :" + (~-5));//-5取反}

结果如下:

这里写图片描述

                3)<<、>>、>>>:

                         这一组操作符的功能都是对源操作数进行移位。其中:

                         <<:左移运算符,x << y,将x向左移动y位,右边出来的空位补0

                         >>:右移运算符,x >> y,将x向右移动y位,左边多出来的位数补上符号位

                         >>>:无符号右移运算符,x >>> y,将x向右移动y位,左边多出来的位数补上符号位

示例程序:

public static void main(String[] args){    //-5的二进制表示是:1111_1111_1111_1111_1111_1111_1111_1011(补码)    //-5左移1位,结果是1111_1111_1111_1111_1111_1111_1111_0110(补码)    //转换成原码:1000_0000_0000_0000_0000_0000_0000_1010,也就是-10    System.out.println("-5 << 1:" + (-5 << 1));    //-5右移1位,结果是1111_1111_1111_1111_1111_1111_1111_1101(补码)    //转换成原码:1000_0000_0000_0000_0000_0000_0000_0011,也就是-3    System.out.println("-5 >> 1:" + (-5 >> 1));//-5右移1位    //-5无符号右移1位,结果是0111_1111_1111_1111_1111_1111_1111_1101(正数的原码和补码相同),即2147483645    System.out.println("-5 >>> 1:" + (-5 >>> 1));//-5无符号右移1位    }

结果:

这里写图片描述

               移位操作符的注意点:

                         1.低于int类型的类型(byte、short、char)在运算的时候,统统先转化为int(这一点和算术运算符相同)

证明:

public static void main(String[] args){        byte bValue = 10;        short sValue = 300;        char cValue = 'a';        byte bResult = bValue << 2;        short sResult = sValue >> 2;        char cResult = cValue >>> 1;    }

结果:

这里写图片描述

由上图可知,各种整型经移位操作后,都转化成了int类型

                         2.当移位的位数超过被移位对象本身的类型的位数,例如 32 >> 100,我们知道32是int类型,它的位数是32,但现在要向右移动100位,这时就需要将移动的位数换成100 % 32 = 4位,即新移动位数 = 原移动位数 % 被移动类型位数,所以32 >> 100 与 32 >> 4 是一样的

证明:

    public static void main(String[] args){        byte bValue = 10;        int result1 = bValue << 66;        int result2 = bValue << 2;        System.out.println("result1 : " + result1);        System.out.println("result2 : " + result2);    }

结果:

这里写图片描述

        由上图可知,将bValue左移66位和左移2位是一样的,因为根据新移动位数 = 原移动位数 % 被移动类型位数,2 = 66 % 8

        4、比较运算符:

                比较运算符包括大于(>)、大于等于(>=)、小于(<)、小于等于(<=)、是否等于(==)、是否不等于(!=),运算结果为布尔类型,若为真则返回true,否则返回false,由于比较运算符比较简单,此处不再赘述。

        5、逻辑运算符:

                逻辑运算符用于操作两个boolean类型的变量或常量。我把它分为以下几类:

                1)与系:

                          包括&&(短路与)和&(非短路与)

                          共同点:两真才真——操作符两边都必须为true,结果才为true

                          不同点:

                          &&是左假即为假——&&左边的操作数如果为false,立即终止计算,返回false

                          &是左假看右边——&左边的操作数为false时,并不立即返回false,还要再看右边的操作数,然后再返回false

示例程序:

public static void main(String[] args){        int iValue1 = 10;        int iValue2 = 1;        //短路与,左边"iValue1 > 10"为false,右边"iValue2++ >= 1"不执行        if((iValue1 > 10) && (iValue2++ >= 1)){            iValue1 = 0;            }        System.out.println("iValue1 :" + iValue1);        System.out.println("iValue2 :" + iValue2);        System.out.println();        //非短路与,两边都会执行        if((iValue1 > 10) & (iValue2++ >= 1)){                iValue1 = 0;            }        System.out.println("iValue1 :" + iValue1);        System.out.println("iValue2 :" + iValue2);    }

效果:

这里写图片描述

                2)或系:

                          包括短路或(||)和非短路或(|),共同点与不同点和与系完全类似:

                          共同点:两真才真——操作符两边都必须为true,结果才为true

                          不同点:

                          ||是左真即为真——||左边的操作数如果为true,立即终止计算,返回true

                          |是左真看右边——&左边的操作数为true时,并不立即返回true,还要再看右边的操作数,然后再返回true

示例程序:

public static void main(String[] args){        int iValue1 = 10;        int iValue2 = 1;        //短路或,左边"iValue1 <= 10"为true,右边iValue2++ >= 1不执行        if((iValue1 <= 10) || (iValue2++ >= 1)){            iValue1 = 0;            }        System.out.println("iValue1 :" + iValue1);        System.out.println("iValue2 :" + iValue2);        System.out.println();        //非短路或,两边都要执行        if((iValue1 <= 10) | (iValue2++ >= 1)){                iValue1 = 0;            }        System.out.println("iValue1 :" + iValue1);        System.out.println("iValue2 :" + iValue2);    }

效果:

这里写图片描述

                3)其他:

                          包括!(非)、^(异或),前者是一个单目运算符,运算规则是——遇true则false,遇false则true,后者是一个双目运算符,运算规则是——不同则true,相同则false

        6、三目运算符:

                          Java中唯一的一个三目运算符是:

                          [expression]?if-true-statement:if-false-statement

                          其中,expression是一个结果为boolean类型的表达式,如果结果为true,则返回if-true-statement,否则返回if-false-statement

示例程序:

public static void main(String[] args){        int iValue = 10;        //[expression]部分为false,返回if-false-statement        System.out.println(iValue > 10 ? "汪峰": "章子怡");        //[expression]部分为true,返回if-true-statement        System.out.println(iValue != 1 ? "汪峰" : "章子怡");    }

效果:

这里写图片描述

0 0
原创粉丝点击