java中一元运算符返回结果为_java中运算符详解

前言

运算符用于执行程序代码运算,会针对一个以上操作数项目来进行运算。JAVA中常见的运算符有很多种,大致分为以下几种,常见的几种运算符如下图:

算术运算符

加、减、乘、除、求余。例++、--、%、/、

赋值运算符

为变量或常量起到赋值作用的。例如=、+=、*=

关系运算符

判断数据大小的,结果为一个布尔值。例如>、>=、!=、==

逻辑运算符

进行逻辑运算,运算的成员为布尔值,结果也为布尔值。例如&&、||、!。

条件运算符

也称三目运算符,表达式为(a

位运算符

对二进制进行操作的,例如&、|、^、~、

一、算术运算符

1.1、常见的算术运算符

+

加法运算;例如x+y

-

减法运算;例如x-y

*

乘法运算;例如x*y

/

除法运算;例如x/y 10/3=3; 10/2.0=5.0

%

取模运算(求余运算);例如x%y  10%3=1

++

自增运算;例如x++,++x

--

自减运算;例如x--,--x

1.2、算术运算中的类型转换

我在我的上一篇博客里面详细讲解了关于JAVA基本数据类型的类型转换了的,可以参考链接:https://blog.csdn.net/qq_37688023/article/details/85106894仔细看一下即可。不过在这里大致说一下其中几个重要的点。

运算时,运算结果会向数据类型大的转换;

在运算时,byte、short、char类型先自动转换为int类型@Test

public void a() {

int a=3;

double b=4;

System.out.println(a+b);//输出7.0

float c=3.2f;

/*c=c+3.14; 编译错误,运算之后变为double类型*/

byte a1=3;

byte b1=4;

/*byte c1=a+b;

* 编译错误,此处由于byte类型参与运算时,先直接转换为int类型,

* 所以最后的结果也是int类型,但是得出的结果不能叫做int类型的直接量,所以编译错误

* */

int d1=a1+b1;

}

1.3、关于i++与++i的区别

i++是++在后,所以先用了再加

++i是++在前,所以先加了再用

注意点:a+++b与a+ ++b的区别  a+++b的含义是(a++)+b;而a+ ++b的含义为a+(++b)

@Test

public void b() {

int a=1;

int b=1;

System.out.println(a++);//输出1

System.out.println(++b);//输出2

int a1=10;

int b1=10;

int sum=a1+++b1;

System.out.println(a1);//输出11

System.out.println(b1);//输出10

System.out.println(sum);//输出20

int a2=10;

int b2=10;

int sum1=a2+ ++b2;

System.out.println(a2);//输出10

System.out.println(b2);//输出11

System.out.println(sum1);//输出21

}

二、赋值运算符

2.1、常见的赋值运算符

运算符

含义

举例=

等于

c=a+b就是将a+b的值赋给c

+=

加等于

a+=1等价于a=a+1

-=

减等于

a-=1等价于a=a-1

*=

乘等于

a*=b等价于a=a*b

/=

除等于

a/=b等价于a=a/b

%=

求余等于

a%=b等价于a=a%b

2.2、关于a+=1与a=a+1的区别

虽然在上面说的a+=1是等价于a=a+1,但是他们两还是有区别的。

@Test

public void c() {

byte a=1;

/*a=a+1;

* 这里会报编译错误,由于a+1出现类型转换,变为int类型,所以再赋值给byte类型所以编译错误

* */

a+=1;

/*这里是不会出现编译错误的,这就是它的特殊之处

* */

System.out.println(a);//输出2

byte b=127;

b+=1;

System.out.println(b);

//输出-128,所以其实就是b=(byte)(b+1);b+1为128,超出byte类型的范围,数据溢出为-128

}

原因:+=运算符,是java语言规定的一元运算符(这里我将它归为赋值运算符有些不妥),Java有自动转换机制,java编译器会对其进行特殊处理,默认的向右转换类型,不需要人工转换。

2.3、各种赋值运算符的例子

@Test

public void d() {

int a=10;

double b=10;

System.out.println(a+=b);

//输出20 a=(int)(a+b)=(int)(10+10)=20

System.out.println(b+=a);

//输出30.0 b=a+b;double类型大,所以不需要自动转换 b=20+10=30.0

int a1=10;

int b1=10;

System.out.println(a1*=b1);//输出100

System.out.println(a1/=b1);//输出10

System.out.println(a1%=b1);//输出0

System.out.println(a1-=b1);//-10

}

三、关系运算符

3.1 常见关系运算符

关系运算符有时候也称为比较运算符,运算的结果一定为布尔值

符号

含义

举例

>

判断是否大于

boolean a=3>2;  a=true

<

判断是否小于

boolean a=3<2;  a=false

>=

判断是否大于等于

boolean a=3<=3;  a=true

<=

判断是否小于等于

boolean a=3>=4;  a=fasle

==

判断是否等于

boolean a=3==4;  a=false

!=

判断是否不等于

boolean a=3!=4;  a=true

注意点:

< 、>、>=、<=只能比较数值类型,所以不能比较布尔类型和大多数应用类型,但是有些基本数据类型包装类型可以。

==、!= 既能比较基本数据类型,也能比较引用数据类型。但是在比较引用数据类型的时候比较的就是地址了。@Test

public void e() {

int a1=10;

int b1=10;

boolean a2=false;

boolean b2=false;

Integer a3=10;

Integer b3=10;

A a4=new A();

A b4=new A();

System.out.println(a1>b1);

/*System.out.println(a2>b2); 非数值类型不能比较大小*/

System.out.println(a3>b3);

/*System.out.println(a4>b4);不能比较大小*/

System.out.println(a1==b1);

System.out.println(a2==b2);//true

System.out.println(a3==b3);

//相等,由于基本数据类型包装类Integer的自动装箱的特性,直接从静态数组中取的,所以不是new的

System.out.println(a4==b4);

//false,由于是new出来的不等

}

3.2、==与equals的区别

首先我们要知道,equals方法是Object类中的一个方法,而Object类是所有类的父类。首先我们先看一下Object类中equals方法的源代码:

public boolean equals(Object obj) {

return (this == obj);

}

可以看出Object类中该方法的逻辑就是==,所以Object类中给出的equals方法就是判断是否==;

那我们再看一下String类的equals方法,如下图:

public boolean equals(Object anObject) {

if (this == anObject) {

return true;

}

if (anObject instanceof String) {

String anotherString = (String)anObject;

int n = value.length;

if (n == anotherString.value.length) {

char v1[] = value;

char v2[] = anotherString.value;

int i = 0;

while (n-- != 0) {

if (v1[i] != v2[i])

return false;

i++;

}

return true;

}

}

return false;

}

可以看出,String类中的equals不再是简简单单的直接判断==;它的equals方法是先判断它们是否==,如果不等再判断两个引用是否为同类或父子类关系,是的话再判断是否值一样,一样则返回true,否则返回fasle。所以使用equals方法时要看该引用对应的类的equals方法的实现逻辑,一般情况下是String的话就是先比较地址,地址相等就为true,不为再比较内容,内容一样也是为true。

所以==与equals的区别可以总结为以下几点:

==是既能比较基本数据类型,比较基本数据类型的时候比较的是值是否相等。又能比较引用数据类型,比较引用数据类型比较的是引用对应的地址是否相等。

而equals是一个方法,所以只能用来比较引用数据类型,要根据类中该方法实现的逻辑是什么来看比较的是什么。一般情况下就是String类型和自定义的类。对应String类型是判断内容是否一致。@Test

public void f() {

String a=new String("abc");//new出来的对象放在了堆中

String b=new String("abc");//不管内容中有无,都是直接new出一个新的对象

String c="abc";//放在常量池中

String d="abc";//现在常量池中找师傅有abc,有的话就将d指向该对象

System.out.println(a.equals(b));//true 只判断内容是否相等

System.out.println(a==b);//false 判断地址是的相等

System.out.println(a.equals(c));//true

System.out.println(a==c);//false 地址不同

System.out.println(a==d);//true 地址一样,由于都指向一个常量池中的同一个对象

}

四、逻辑运算符

4.1、常用逻辑运算符

首先逻辑运算符运算的对象必须还是布尔值,即符号两边必须是布尔类型。

运算符

名称

举例

&&

a&&b,a和b都为true,结果才为true,否则为false

||

a||b,a和b都为false,结果才为false,否则为true

!

!a,a为false,则结果为true。即结果相反变量a

变量b

a&&b

a||b

!a

true

true

true

true

false

true

false

false

true

false

false

false

false

false

true

false

true

false

true

true

4.2、关于逻辑运算符中"短路"的问题

对于&&而言,当第一个操作数为false时,将不会判断第二个操作数。

对于 || 而言,当第一个操作数为true是,将不会判断第二个操作数。@Test

public void g() {

int a=10;

int b=10;

boolean c=a>10 && b++>10;

System.out.println(c);

System.out.println(b);//输出10,由于a>10已经为False之后,后面的b++也就不会执行

boolean d=a<11 || b++>10;

System.out.println(d);

System.out.println(b);//也是输出10,前面的a<11已经为true,所以后面的b++也不执行

}

五、条件运算符

即为三目运算符,形式为:布尔表达式 ? 表达式1 :表达式2

运算过程:如果布尔表达式的值为 true,则返回 表达式1 的值,否则返回表达式2的值

用处:和if else的分支结构作用有点类似。但是写法比 if else简洁。

@Test

public void h() {

int[] a= {-1,2,0};

for(int i=0;i

a[i]=a[i]>=0?a[i]:0;//将数组中小于0的数字变为0

}

for(int b:a) {

System.out.println(b);//利用增强for循环输出数组中的值

}

}

六、位运算符

6.1、常用位运算符

符号

含义

&

按位与

|

按位或

~

非(取反运算符)

^

异或

<<

左移运算符

>>

右移运算符

>>>

无符号右移运算符

6.2、按位与 & 详解

按位与 '&' 与逻辑与 '&&' 不同,逻辑与 '&&' 只能操作布尔类型的值,而按位与 '&'不仅能操作布尔类型的值,还能操作整数型基本类型。且按位与 '&' 不像逻辑与 '&&'一样有短路效应。

操作布尔类型的值时,与逻辑与 '&&' 类似,也是见false则false,就是没有短路效应。

操作整数基本数据类型是,即将整数化为二进制,然后相同位上计算,相同位都是1则结果为1,否则为0

例如:3&4

3的二进制为    0000 0000 0000 0011

4的二进制为    0000 0000 0000 0100

则结果为         0000 0000 0000 0000 对应的二级制为0,所以3&4=0;

(1)按位与的常见作用:清0,取一个数中的指定位数(例如取int类型值的低八位)

例如int类型变量a对应的二进制为 0010 0001 0000 1010 ,现在求它的低八位,也就是1010,就可以使用a&15

15对应的二进制为 0000 0000 0000 1111  所以 ,a&15的结果就为 0000 0000 0000 1010

(2)判断一个数的奇偶性:n&1 == 1?”奇数”:”偶数”

(3)面试题:优化n%8

解答:n&7

原因:对8取模(求余)运算的定义就是整除8后的余数,而对于8来说,这个余数恰好就是这个数的二进制表示的低3位; 因此对8取模等价于获取数据的低3位,这由恰好等价于 &7 的结果。

6.3、按位或 | 详解

按位或 '|' 与逻辑或 '||' 不同,逻辑与 ' || ' 只能操作布尔类型的值,而按位与 ' | '不仅能操作布尔类型的值,还能操作整数型基本类型。且按位或 '|' 不像逻辑或 ' || '一样有短路效应。

操作布尔类型的值时,与逻辑或 ' || ' 类似,也是见true则true,就是没有短路效应。

操作整数基本数据类型是,即将整数化为二进制,然后相同位上计算,只要有一个1就为1,否则结果为0

例如 3 | 4

3的二进制为    0000 0000 0000 0011

4的二进制为    0000 0000 0000 0100

则结果为          0000 0000 0000 0111 对应的二级制为7,所以3&4=7;

按位或的作用:将一个数的某些位置变为1

6.4、按位非 ~详解

也称为取反运算符,是一个一元运算符,所以只能对一个操作数进行操作。按位非就是将各位数字取反,0变为1,1变为0;

例如   4的二进制为 0000 0000 0000 0100

所以~4的二进制为  1111 1111  1111  1011 转换为是十进制为-5

常见作用:一个数的相反数=该数取反+1例如4的相反数-4=~4+1=-5+1=-4

6.5、异或 ^ 详解

将数转换为二进制之后运算,然后不相同的结果就为1;  0^0=0  1^0=1  0^1=1  1^1=0

例子:4的二进制为  0000 0000 0000 0100

5的二进制为  0000 0000 0000 0110

4^5的二级制为  0000 0000 0000 0010 转换为十进制为2

异或^的作用实例:不适用临时变量交换两个数

我们经常写变量交换时,是以如下,用了一个临时变量来交换的;

@Test

public void a() {

int a=3;

int b=4;

int c;//定义的临时变量

c=a;

a=b;

b=c;

System.out.println(a);//输出4

System.out.println(b);//输出3

}

但是利用异或运算符不用使用临时变量

@Test

public void b() {

int a=3;

int b=4;

a=a^b;

b=b^a;//b=b^(a^b) ->b=a

a=a^b;//a=(a^b)^(b^a)->a=b

System.out.println(a);//输出4

System.out.println(b);//输出3

}

6.6、左移、右移、无符号右移动

左移运算符 <

右移运算符 >> :是低位溢出,符号位不变,并用符号位补溢出高位

无符号右移运算符>>>:低位溢出,高位补0,注意,无符号右移(>>>)中的符号位(最高位)也跟着变,无符号的意思是将符号位当作数字位看待。@Test

public void c() {

int a=4;

System.out.println(a<<2);

/* 0000 0000 0000 0100 a的二进制

* 000000 0000 0001 0000 低位补两个0

* 0000 0000 0001 0000 高位溢出,所以a<<2=8

* */

System.out.println(a>>2);

/*0000 0000 0000 0100

* 0000 0000 0000 000100 符号位补高位

* 0000 0000 0000 0001 低位溢出 所以 a>>2=1

* */

int b=-1;

System.out.println(b>>>1);

/* 1111 1111 1111 1111

* 0111 1111 1111 11111 右移一位,高位补0,

* 0111 1111 1111 1111 低位溢出 结果为 2147483647

* */

}

七、各种运算符的优先级

下图为java中各种运算符的优先级,可以记一下,但有时候不太清楚的时候就直接用括号()吧!

运算符

结合性

[ ]  .  ( ) (方法调用)

从左向右

! ~ ++ -- +(一元运算) -(一元运算)

从右向左

*  /  %

从左向右

+ -

从左向右

<< >> >>>

从左向右

< <= > >= instanceof

从左向右

== !=

从左向右

&

从左向右

^

从左向右

|

从左向右

&&

从左向右

||

从左向右

?:

从右向左

=

从右向左

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值