Java运算符

一、运算符简单认识

       运算符是一种特殊的符号,用以表示数据的运算、赋值和比较等。

       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
    ~:取反
    <<:左移位
    >>:右移位
    >>>:无符号右移位

位运算符的运算结果表:
Java运算符_第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后的代码块可以有多个语句,但三目运算符是不支持多个语句的。

三、 运算符优先级
Java运算符_第2张图片
注意:
不要把一个表达式写的过于复杂,如果一个表达式过于复杂,则把它分成几步来完成。
不要过多地依赖运算符的优先级来控制表达式的执行顺序,这样可读性太差,尽量使用()来控制表达式的执行顺序。

你可能感兴趣的:(java,运算符,三目运算符,逻辑运算符,比较运算符)