3.2 关系与逻辑运算
关系运算总是生成boolean型结果,其计算的是操作数之间的关系。如果关系描述是正确的,则返回true;否则,返回false。Java中的关系运算符如下所示。
· “==”:等于。
· “!=”:不等于。
· “>”:大于。
· “>=”:大于或等于。
· “<”:小于。
· “<=”:小于或等于。
3.2.1 等于/不等于运算
“==”(等于)与“!=”(不等于)适用于所有基本数据类型以及引用类型,对于基本数据类型,比较两个值是否相等(不等);对于引用类型,比较引用的是否是(不是)同一个对象。本小节主要介绍对基本数据类型的操作。
1.“==”运算符
“==”运算符是用于测试两个操作数是否相等的运算符。若相等则返回true,否则返回false,例如:
1 boolean a=(true==false); //返回结果false并将其赋给a 2 boolean b=(15.0==15.0); //返回结果true并将其赋给b 3 boolean c=(a==b); //返回结果false并将其赋给c
要注意的是,“==”运算符不但可以对类型相同的值进行比较;对于类型不同的值只要具有可比性,也可以进行比较,例如,所有的数值型值之间可以相互比较。
1 boolean b=(12.0==12); 2 b=('a'==97.0);
2.“!=”运算符
与等于运算符“==”一样,不等于运算符“!=”也是用来测试两个操作数是否相等的运算符,不同的是若相等则返回false,否则返回true,例如:
1 boolean a=( true!=false); //返回结果true并将其赋给a 2 boolean b=(15.0!=15L); //返回结果false并将其赋给b 3 boolean c=( a!=b); //返回结果true并将其赋给c
与“==”一样,“!=”也可以对类型不同的值进行比较,例如:
1 boolean b=(12.0!=12); 2 b=('a'!=97.0);
提示:不同类型的数据进行比较,要有可比性,否则编译报错。对八种基本数据类型来说,boolean型只能与boolean型比较,其他七种则可以相互比较。
3.无穷大与“NaN”的比较
Java中浮点运算的结果可能产生正负无穷大与“NaN”,同样可以用等于(不等于)运算来判断运算的结果是否是它们,例如:
1 //代码实现 2 public class Sample3_6 3 { 4 public static void main(String args[]) 5 { 6 System.out.println((12.0/0)==Double.POSITIVE_INFINITY); 7 System.out.println((-12.0/0)==Double.NEGATIVE_INFINITY); 8 System.out.println((12.0%0)); 9 System.out.println((12.0%0)==Double.NaN); 10 } 11 }
编译运行如上代码,结果如图3-8所示。
图3-8 Sample3_6的编译运行结果
从图3-8中可以看出:
· “(12.0/0)”的结果是正无穷大,所以打印“true”。
· “(−12.0/0)”的结果是负无穷大,所以也打印“true”。
· “(12.0%0)”的结果是“NaN”。
· “(12.0%0)==Double.NaN”的结果为“false”。因为“NaN”表达的意思是“不知道”,“不知道”并不一定等于“不知道”,所以Java中规定两个“NaN”相比返回“false”。
3.2.2 比较大小运算
比较大小运算符可以用来比较数值型数据的大小。在八种基本数据类型中,除了boolean型外都可以相互进行比较。在Java中,比较大小运算符包括四种,如下所示。
· “>”:大于。
· “>=”:大于或等于。
· “<”:小于。
· “<=”:小于或等于。
下面的代码说明了其具体使用方法。
1 boolean a=(700>200); //返回结果true并将其赋给a 2 boolean b=('a' >97.0); //返回结果false并将其赋给b,“a”的Unicode编码为97 3 boolean c=(700>=200); //返回结果true并将其赋给c 4 boolean d=(300<100L); //返回结果false并将其赋给d 5 boolean e=(15.0<=16L); //返回结果true并将其赋给e
提示:比较大小运算符还可以用来对无穷大、“NaN”进行比较。将数值与无穷大进行比较是有意义的,而与“NaN”进行比较没有意义,Java中规定任何数值与“NaN”进行大小比较永远返回“false”。
逻辑运算符能够对逻辑值进行逻辑运算,产生一个boolean型的结果,其操作数只能是boolean型。Java中的逻辑运算符包括与运算、或运算、非运算,下面将对这三种逻辑运算进行介绍。
3.2.3 “与”运算
“与”运算的规则是:当两个操作数全部为true时,返回true;否则返回false。在Java中,与运算符有两种,分别为:
· 短路与“&&”。
· 非短路与“&”。
1.短路与“&&”
“&&”运算符的特点体现为它不在无意义的计算上浪费时间,有时也称其为“聪明”与。“&&”运算符先计算左边的操作数。如果该操作数解析为false,则“&&”运算符不再关心右边的操作数,而直接返回false。因为左边操作数为false,则其整个结果必为false,没有必要再进行计算。
下面的例子说明了其工作过程,请读者考察如下代码。
1 //代码实现 2 public class Sample3_7 3 4 public static void main(String args[]) 5 { 6 int a=3; 7 int b=4; 8 boolean m=(++a>5) && (++b>5); 9 System.out.println("a="+a+", b="+b); 10 } 11 }
将上述代码编译运行,其结果如图3-9所示。
图3-9 Sample3_7的编译运行结果
从图3-9中可以发现变量b并没有进行自增运算,这说明操作符“&&”之后的语句没有执行。因为操作符之前的操作数“(++a>5)”的结果为false。
2.非短路与“&”
“&”不是短路运算符,所以总是计算其两边的内容,这样,其计算效率便会下降。
若将代码“Sample3_7”中的第8行改为:
boolean m=(++a>5)& (++b>5);
编译运行后,其结果将如图3-10所示。
图3-10 Sample3_7修改后的运行结果
从图3-10中可以发现,两个变量都做了自增运算,说明两边都执行了。
3.2.4 “或”运算
“或”运算的规则是:当两个操作数全部为false时,返回false;否则返回true。其与“与”运算一样有两种,如下所示:
· 短路或“||”。
· 非短路或“|”。
1.短路或“||”
“||”运算符的特点和“&&”运算符一样,即体现为不在无意义的计算上浪费时间。“||”运算符先计算左边的操作数,如果该操作数解析为true,则“||”运算符不再关心右边的操作数。因为左边操作数为true,则其整个结果必为true。
下面的例子说明了其工作过程,请读者考察如下代码。
1 //代码实现 2 public class Sample3_8 3 { 4 public static void main(String args[]) 5 { 6 int a=3; 7 int b=4; 8 boolean m=(++a<5) || (++b<5); 9 System.out.println("a="+a+", b="+b); 10 } 11 }
将上述代码编译运行,其结果如图3-11所示。
图3-11 Sample3_8的编译运行结果
从图3-11中可以发现,变量b并没有进行自增运算,说明操作符“||”之后的语句没有执行。因为操作符之前的操作数“(++a>5)”返回结果为true。
2.非短路或“|”
“|”与“&”一样,不是短路运算符。因此,总是计算其两边的内容,这样,其计算的效率便会下降。将代码“Sample3_8”中的第8行改为:
boolean m=(++a<5) | (++b<5);
编译运行后,其结果将如图3-12所示。
图3-12 Sample3_8改后的编译运行结果
从图3-12中可以发现,两个变量都做了自增运算,说明两边都执行了。
提示:在日常开发中没有特殊的需要一般应该采用短路逻辑运算,这样可以大大提高运算效率。但在使用短路逻辑运算时要注意,最好不要在逻辑表达式中修改变量的值,因为有时执行,有时不执行,可能会带来意想不到的bug。
3.2.5 “非”运算
“非”运算的规则是:若操作数的值为true,则返回false;否则返回true。其用符号“!”标记,例如:
1 boolean a=!(200>100); //结果将返回false 2 boolean b=!(20<10); //结果将返回true
读者会发现,括号内解析出的布尔值,经过“!”运算后,结果全部取反。