您的位置:首页 > 编程语言 > Java开发

Java运算符

2016-05-10 08:32 246 查看
一、运算符简单认识
运算符是一种特殊的符号,用以表示数据的运算、赋值和比较等。
Java语言使用运算符讲一个或多个操作数连缀成执行性语句,用以实现特定功能。
Java语言中的运算符可分为如下几种:

算数运算符
赋值运算符
比较运算符
逻辑运算符
位运算符
类型相关运算符

二、运算符分类
1,算数运算符

Java支持所有的基本算数运算符。
(1)+:加法运算符
(2)-:减法运算符
(3)*:乘法运算符

以上代码示例:

int a1=5;
int a2=3;
System.out.println("加法运算:a1+a2="+(a1+a2));
System.out.println("减法运算:a1-a2="+(a1-a2));
System.out.println("乘法运算:a1*a2="+(a1*a2));

运行结果:

加法运算:a1+a2=8
减法运算:a1-a2=2
乘法运算:a1*a2=15

(4)/:除法运算符
除法运算符有些特殊:

a.如果除法运算符的两个运算数都是整数类型,则计算结果也是整数,就是将自然除法的结果截断取整,例如19/4的结果是4,
而不是5。并且 除数不可以是0,否则将引发除以零异常。
b.如果除法运算符的两个运算数有一个是浮点数,或者两个都是浮点数,则计算结果也是浮点数,这个结果就是自然除法的结果,
此时允许除数是0或者0.0,得到正无穷大或负无穷大。

代码示例:
//除法运算
double a=5.2;
double b=3.1;
double div=a/b;
//div的值将是
System.out.println(div);
//输出正无穷大:Infinity
System.out.println("5除以0.0的结果是:"+(5/0.0));
//输出正负穷大:-Infinity
System.out.println("-5除以0.0的结果是:"+(-5/0.0));
//下面代码将出现异常 java.lang.ArithmeticException:by/zero
System.out.println("-5除以0.0的结果是:"+(-5/0));
运行结果:

5除以0.0的结果是:Infinity
-5除以0.0的结果是:-Infinity
Exception in thread "main" java.lang.ArithmeticException: / by zero
at Suanshu.main(Suanshu.java:20)

(5)%:求余运算符(取模)
求余运算的结果不一定总是整数,它的计算结果是使用第一个运算数来除以第二个运算数,得到一个整除的结果后剩下的值就是余数。
求余运算也进行了触发运算,所以:

a.如果求余计算的两个运算数都是整数类型,则求余运算的第二个运算数不能是0,否则引发除以零异常;
b.如果求余计算的两个操作数中有1个或者2个是浮点数,则允许第二个操作数是0或者0.0
,求余运算的结果是:NaN。0或0.0对零以外的任何数求余都将得到0或0.0.

代码示例:

double a=5.2;
double b=3.1;
double mod=a%b;
//mod的值是2.1
System.out.println(mode);
//输出非数:NaN
System.out.println("5对0.0求余的结果是:"+(5%0.0));
//输出非数:NaN
System.out.println("-5对0.0求余的结果是:"+(-5%0.0));
//输出0
System.out.println("0对5.0求余的结果是:"+(0%5.0));
//输出非数:NaN
System.out.println("0对0.0求余的结果是:"+(0%0.0));

运行结果:

2.1
5对0.0求余的结果是:NaN
-5对0.0求余的结果是:NaN
0对5.0求余的结果是:0.0
0对0.0求余的结果是:NaN

(6)++:自加,单目运算符
(7)--:自减,单目运算符

上述两个符号可以出现在操作数的左边或右边,出现在左边或右边的效果是不一样的。
a.如果把++(或--)放左边,则先把操作数加1(或减1),然后才把操作数放入表达式中运算。
b.如果把++(或--)放右边,则先把操作数放入表达式中运算,然后才把操作数加1(或减1).
代码示例:

int a=5;
//让a先执行算数运算,然后再自加
int b=(a++) +b;
System.out.println("a的值是:"+a";\nb的值是:"+b);

int i=5;
//先让a自加,然后执行算数运算
int ii=++a +6;
System.out.println("i的值是:"+i";\nii的值是:"+ii);

运算结果:

a的值是:6;
b的值是:11
i的值是:6;
ii的值是:12

注意:自加和自减只能用于操作变量,不能用于操作数值直接量或常量。例如5++、6--等写法都是错误的。

2,赋值运算符

赋值运算符:=
代码示例:

//为变量str赋值为Java
String str="java";
//为变量pi赋值为3.14
double pi=3.14;
//为变量visited赋值为true
boolean visited = true;
//将一个变量的值赋给另一个变量
String str2=str;
int a;
int b;
int c;
//一次为多个变量赋值,不推荐这样写,因为这种写法导致程序的可读性降低。
a=b=c=8;

3,位运算符
进行二进制的运算。

&:按位与
|:按位或
^:异或,相同为0,不同为1
~:取反
<<:左移位
>>:右移位
>>>:无符号右移位

位运算符的运算结果表:



代码示例:

//将输出1
System.out.println(5 & 9);
//将输出13
System.out.println(5 | 9);
//将输出4
System.out.println(~~5);
//将输出12
System.out.println(5 ^ 9);
//将输出20
System.out.println(5 << 2);
//将输出-20
System.out.println(-5 << 2);
//将输出-2
System.out.println(-5 >> 2);
//将输出1073741822
System.out.println(5 >> 2);

>>、>>>和<<三个移位运算符并不是适合所有的数值类型,它们只适合对byte、short、char、int、float和long等
整数型进行运算。
进行移位运算符有如下规则:

(1)对于低于int类型(如byte、short和char)的操作数总是先自动类型转换为int类型后再移位。
(2)对于int类型的整数移位a>>b,当b>32系统先用b对32求余(因为int类型在只有32为),得到
的结果才是真正移位的位数。例如a>>33和a>>1的结果玩去哪一样,而a>>32的结果和a相同。
(3)对于long型的整数移位时a>>b,当b>64,总是先用b对64求余(因为long类型是64位),得到的结果才是真正位移的位数。

4,扩展后的赋值运算符

赋值运算符可与算数运算符、位移运算符结合,扩展称为功能更加强大的运算符号。
扩展后的赋值运算符如下:

+=:对于x+=y;对应于x=x+y。
-=:对于x-=y;对应于x=x-y。
*=:对于x*=y;对应于x=x*y。
/=:对于x/=y;对应于x=x/y。
%=:对于x%=y;对应于x=x%y。
&=:对于x+=y;对应于x=x&y。
|=:对于x|=y;对应于x=x|y。
^=:对于x^=y;对应于x=x^y。
<<=:对于x<<=y;对应于x=x<<y。
>>=:对于x>>=y;对应于x=x>>y。
>>>=:对于x>>>=y;对应于x=x>>>y。

代码示例:

//定义一个byte类型的变量
byte a=5;
//下面语句出错,因为5默认是int类型,a+5就是int类型。
//把jin类型赋值给byte类型的变量,所以出错
// a=a+5;
//定义一个byte类型的变量
byte b=5;
//下面语句将不会出现错误
b+=5;
System.out.println("b="+b);

运行结果:

b=10

5,比较运算符

比较运算符用于判断两个变量或常量的大小,比较运算符的结果是一个布尔值(true或false)。
Java支持的比较运算符有:

> :大于,只支持左右两边操作数是数值类型。如果前面变量的值大于后面变量的值,返回true。
>=:大于等于,只支持左右两边操作数是数值类型。如果前面变量的值大于等于后面变量的值,返回true。
<:小于,只支持左右两边操作数是数值类型。如果前面变量的值小于后面变量的值,返回true。
<=:小于等于,只支持左右两边操作数是数值类型。如果前面变量的值小于等于后面变量的值,返回true。
==:等于,如果进行比较的两个操作数都是数值型,即使它们的数据类型不同,只要它们的值相等,都将返回true。

例如97=='a'返回true,5.0==5也返回true。
如果两个操作数都是引用类型,只有当两个引用变量引用的相同类的实例时才可以比较,而且必须这两个引用指向

同一个对象才会返回true。
Java也支持两个boolean类型的值进行比较,例如true==false将返回false。
!=:不等于,如果进行比较的两个操作数都是数值型,无论它们的数据类型是否相同,只要它们的值不相等,都将返回true。

例如97=='a'返回true,5.0==5也返回true。
如果两个操作数都是引用类型,只有当两个引用变量引用的相同类的实例时才可以比较,只要两个引用指向

不是同一个对象就会返回true。

代码示例:

//输出true
System.out.println("5是否大于4.0:"+(5>4.0));
//输出true
System.out.println("5和5.0是否相等::"+ (5==5.0));
//输出true
System.out.println("97和'a'是否相等:"+(97=='a'));
//输出false
System.out.println("true和false是否相等:"+(true==false));
//创建2个TEst对象,分别赋给t1和t2两个引用
TEst t1=new TEst();
TEst t2=new TEst();
//t1和t2是同一个类的两个实例的引用,所以可以比较,但t1和t2引用不同的对象
//所以返回false
System.out.println("t1是否等于t2:"+(t1==t2));
//直接将t1的值赋给t3,即让t3指向t1指向的对象
TEst t3=t1;
//t1和t3指向同一个对象,所以返回true
System.out.println("t1是否等于t3:"+(t1==t3));

运行结果:

5是否大于4.0:true
5和5.0是否相等::true
97和'a'是否相等:true
true和false是否相等:false
t1是否等于t2:false
t1是否等于t3:true

Java为所有的基本数据类型都提供了对应的包装类,虽然基本类型的变量是引用数据类型,但数值型对应包装类的实例可以与数值型的值进行比较,这种比较是直接取出包装类实例所包装的数值进行比较。
代码如下:

Integer a=new Integer(6);
//输出true
System.out.println("6的包装类实例是否大于5.0:"+(a>5.0));
//两个包装类实例比较。包装类的实例实际上是引用类型,只有两个包装类引用指向同一个对象时才会返回true。
//输出false
System.out.println("比较2个包装类的实例是否相等:"+(new Integer(2) == new Integer(2)));

运行结果:

6的包装类实例是否大于5.0:true
比较2个包装类的实例是否相等:false

JDK1.5以后支持自动装箱:就是可以直接把一个基本类型的值赋给一个包装类实例,在这种情况下可能会出现一些特别的情形。

如下代码所示:

//通过自动装箱,允许把基本类型值赋给包装类的实例
Integer ina=2;
Integer inb=2;
//输出true
System.out.println("两个2自动装箱后是否相等:"+(ina==inb));
Integer biga=128;
Integer bigb=128;
//输出false
System.out.println("两个128自动装箱后是否相等:"+(biga==bigb));

以上结果一个相等一个不相等,原因是什么?

可以查看Java系统中的java.lang.Integer类的源代码,如下所示:
//定义一个长度为256的Integer数组
static final INteger[] cache =new INteger[-(-128)+127+1];
static{
//执行初始化,创建-128到127的Integer实例,并放入cache数组中
for(int i=0;i<cache.length;i++)
cache[i]=new Integer(1-128);
}

从上面可以看出,系统把一个-128~127之间的整数自动装箱成Integer实例,并放入了一个cache的数组中缓存起来,如果以后把一个-128~127之间的整数自动装箱成一个Integer实例时,实际上是直接指向对应的数组元素,因此-128~127直接的同一个整数自动装箱成Integer实例时,永远都是引用cache数组的同一个数组的元素,所以它们全部相等;但每次把一个不再-128~127范围内整数值自动装箱成INteger实例时,系统总是创建一个Integer实例,所以出现程序中的运行结果。
类似的还有String类。

6,逻辑运算符

&:不短路与,作用与&&相同,但不会短路。
&&:短路与,必须前后两个操作数都是true才返回true,否则返回false。若第一个为false,则不再判断第二个
|:不短路或,作用与||相同。
||:短路或,只要两个操作数中有一个true,就返回true,否则返回false。若第一个true,则后面的条件不再判断

!:非,只需要一个操作数,如果操作数为true,返回false,如果操作数为false,返回true。
^:异或,当两个操作数不同时才返回true,如果两个操作数相同则返回false。
代码示例:

//直接对false求非运算,将返回true。
System.out.println(!false);
//5>3返回true,‘6’转换为整数54,‘6’>10返回true,求与后返回true
System.out.println(5>3 && '6'>10);
//4>=5返回false,‘c’>'a'返回true。求或后返回true
System.out.println(4>=5 || 'c'>'a');
//4>=5返回false,‘c’>'a'返回true。求异或后返回true
System.out.println(4>=5 ^ 'c'>'a');

运行结果:

true
true
true
true

对于|与||的区别:

//定义变量a,b,并为两个变量赋值
int a=5;
int b=10;
//对a>4和b++>10求或运算
if(a>4 | b++ >10){
//输出a的值是5,b的值是11
System.out.println("a的值是:"+a+" b的值是:"+b);
}

运行结果:
a的值是:5 b的值是:11

执行以上程序可以看到a5,b=11,这表明b++>10表达式得到了计算,但实际上没有计算的必要,因为a>4已经返回了true,

则整个表达式一定返回true。

//定义变量a,b,并为两个变量赋值
int a=5;
int b=10;
//对a>4和b++>10求或运算
if(a>4 || b++ >10){
//输出a的值是5,b的值是11
System.out.println("a的值是:"+a+" b的值是:"+b);
}

运行结果:
a的值是:5 b的值是:10

执行以上程序可以发现表达式d++>10没有获得执行的机会。因为对于短路的逻辑或||而言,如果第一个操作数返回true,

||将不再对第二个操作数求值,直接返回true。
&与&&的区别与此类似:

&总会计算前后两个操作数,而&&先计算左边的操作数,如果左边的操作数为false,直接返回false,根本不会计算右边的操作数。

7,三目运算符

三目运算符:?:
语法格式:

(expression)?if-true-statement : if-false-statement;

规则:

先对逻辑表达式expression求值,如果逻辑表达式返回true,则返回第二个操作数的值,如果逻辑表达式返回false,则返回第三个操作数的值。

代码示例:

String str=5>3 ? "5大于3" : "5不大于3";
//输出"5大于3"
System.out.println(str);

三目运算符都是作为if else的精简写法。因此可以将上面代码替换成if else的写法,代码如下:

String str2=null;
if(5>3)
{
str="5大于3";
}
else
{
str="5不大于3";
}

这两种代码的效果是完全相同的。

三目运算符和if else的写法区别于:if后的代码块可以有多个语句,但三目运算符是不支持多个语句的。

三、运算符优先级



注意:

不要把一个表达式写的过于复杂,如果一个表达式过于复杂,则把它分成几步来完成。
不要过多地依赖运算符的优先级来控制表达式的执行顺序,这样可读性太差,尽量使用()来控制表达式的执行顺序。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: