Java的运算符

Java有4大类运算符:算术运算、位运算、关系运算和逻辑运算。

运算符的优先级

优先级 运算符
1 ( ) [ ] .(点运算符)
2 ! ++ -- ~ +(正) -(负)
3 * / %
4 + -
5 >> >>> <<
6 < <= > >=
7 == !=
8 &
9 ^
10 |
11 &&
12 ||
13 ?:
14 = += -+ *= /= %=

模运算符

Java中,模运算符不止可以用在对整数类型取模,还可以用在浮点类型(这点跟很多其他的编程语言不一样),如

int x = 9;
double y = 40.5;
System.out.println(y%x);

运行结果:
4.5

复合赋值运算符

复合赋值运算符:“+=”,“-=”,“*=”,“/=”,“%=”(两个运算符中间不要有空格)

对于,javatotal *= sum + 12;等价于:total = total * (sum + 12);

有关“++”(“--”也适用)运算符的说明:

public class Hello {
    public static void main(String[] args) {
        int i = 10;
        int k = i + ++i;
        System.out.println(k);
        i = 10;
        int j = i++ + i;
        System.out.println(j);
        i = 10;
        int m = i + i++;
        System.out.println(m);
        i = 10;
        int n = ++i +i;
        System.out.println(n);
    }
}

运行结果:
21
21
20
22
  • 首先声明,
    当 i = 10 时,进行 “i++” 运算后, i 的值是 11,而“i++”这个表达式的值是10;
    当 i = 10 时,进行 “++i” 运算后, i 的值是 11,而“++i”这个表达式的值也是11;
  • 优先级相同的四则运算,运算顺序是从左往右的。
    对于int k = i + ++i;,左边的 i 取值为 10,右边的 i 取值也为10,此时先计算 “++i” 的值(“++”,“--”为单目运算符,运算优先级比算数运算高),为11。所以 k 的值为 21。
    对于int j = i++ + i;,左边的 i 取值为 10,先进行 “i++” 的运算,此时 i = 11,“i++” 的值为10。所以 j 的值为 21。
    对于int m = i + i++;,左边的 i 取值为10,右边的 i 取值也为 10,而 “i++” 的值为 10,故 m 的值为 20。
    对于int n = ++i +i;,左边的 i 取值为 10,经过 “++i” 的计算表达式值为 11,i 的值为11,故 n 的值为 22。

运算符“++”前置等价于“+=1”。如,有int i = 1,则“++i” 与“i += 1”效果一样,表达式的值都为2。

int i = 1;
System.out.println(i+=1);

运算结果:
2
int i = 1;
System.out.println(++i);

运算结果:
2
int i = 1;
System.out.println(i++);

运算结果:
1

位运算符

Java定义的位运算(bitwise operators)直接对整数类型的位进行操作,这些整数类型包括long,int,short,char和 byte。

运算符 结果
~ 按位非(NOT)(一元运算)
& 按位与(AND)
| 按位或(OR)
^ 按位异或(XOR)
>> 右移
>>> 右移,左边空出的位以0填充
<< 左移
&= 按位与赋值
|= 按位或赋值
^= 按位异或赋值
>>= 右移赋值
>>>= 右移赋值,左边空出的位以0填充
<<= 左移赋值

Java使用大家知道的2的补码 (two's complement) 这种编码来表示负数,也就是通过将与其对应的正数的二进制代码取反(即将1变成0,将0变成1),然后对其结果加1。要对一个负数解码,首先对其所有的位取反,然后加1。

位逻辑运算符

按位非也叫做补,一元运算符NOT“~”是对其运算数的每一位取反。
按位与运算符“&”,如果两个运算数都是1,则结果为1。
按位或运算符“|”,任何一个运算数为1,则结果为1。
按位异或运算符“^”,只有在两个比较的位不同时其结果是 1。否则,结果是零。

按位异或运算符有一个有用的属性,如

00101010 42
^00001111 15
---------------
00100101 37

可以看到,通过按位异或,取出了低位的值。

左移运算符

左移运算符<<使指定值的所有位都左移规定的次数。它的通用格式如下所示:
value << num
每左移一个位,高阶位都被移出(并且丢弃),并用0填充右边。

在对byte和short类型的值进行移位运算时,由于Java会自动把这些类型扩大为 int型,而且,表达式的值也是int型 。对byte和short类型的值进行移位运算的结果是int型,而且如果左移不超过31位,原来对应各位的值也不会丢弃。但是,如果你对一个负的byte或者short类型的值进行移位运算,它被扩大为int型后,它的符号也被扩展。这样,整数值结果的高位就会被1填充。因此,为了得到正确的结果,你就要舍弃得到结果的高位。这样做的最简单办法是将结果转换为byte型。

public class test {

    public static void main(String[] args) {
        byte a = 64, b;
        int i;
      
        byte c = -64, d;
        int j;
      
        j = c << 2;
        i = a << 2;
        d = (byte)(c << 2);
        b = (byte) (a << 2);
      
        System.out.println("Original value of a: " + a);
        System.out.println("i and b: " + i + " " + b);
        
        System.out.println("Original value of c: " + c);
        System.out.println("i and b: " + j + " " + d);
        }

}

该程序产生的输出下所示:
Original value of a: 64
i and b: 256 0
Original value of a: -64
i and b: -256 0

每次左移都可以使原来的操作数翻倍,所以这个办法可以用来进行快速的2的乘法。但是,如果将1移进高阶位(31或63位),那么该值将变为负值。

class MultByTwo {
    public static void main(String args[]) {
        int i;
        int num = 0xFFFFFFE;
        for(i=0; i<4; i++) {
            num = num << 1;
            System.out.println(num);
        }
    }
}

该程序的输出如下所示:
536870908
1073741816
2147483632
-32
右移运算符

右移运算符>>使指定值的所有位都右移规定的次数。它的通用格式如下所示:
value >> num
这里,num指定要移位值value移动的位数。

将值每右移一次,就相当于将该值除以2并且舍弃了余数。

所以,如果想利用这个特点将一个整数进行快速的2的除法,需要确保你不会将该数原有的任何一位移出。

右移时,被移走的最高位(最左边的位)由原来最高位的数字补充。如果要移走的值为负数,每一次右移都在左边补1,如果要移走的值为正数,每一次右移都在左边补0,这叫做符号位扩展(保留符号位)(sign extension),在进行右移操作时用来保持负数的符号。

由于符号位扩展(保留符号位)每次都会在高位补1,因此-1右移的结果总是–1。(-1的二进制补码是全1)

若不希望在右移时保留符号,用按位与可以实现。如,要进行运算的是byte型的数,则将它的值转换为用十六进制表示。注意右移后的值与0x0f进行按位与运算,这样可以舍弃任何的符号位扩展。

无符号右移

当处理像素值或图形时,就常常不希望进行符号位扩展。

Java的无符号右移运算符>>>,总是在左边补0。

由于无符号右移运算符>>>总是把short和byte型的数据扩大为int型,所以只是对32位和64位的值有意义。如,

byte b = (byte) 0xf1;
byte d = (byte) (b >>> 4);

运算结果d的值为0xff。

关系运算符

在C/C++中,这些类型的语句是很常见的:

int done;
// ...
if(!done) ... // Valid in C/C++
if(done) ... // but not in Java 

而在Java中,这些语句必须写成下面这样:

if(done == 0)) ... // This is Java-style.
if(done != 0) ...

因为在C/C++中,任何非0的值为真,而0值是假。但是,Java中真值、假值跟数字没有关系。

所有的关系运算符的优先级比算数运算的低,但是比赋值运算的高。

判断是否相等的 == 和 != 的优先级比其他的低,而连续的关系运算是从左到右进行的。

布尔逻辑运算符

运算符 含义
& 逻辑与
| 逻辑或
^ 异或
|| 短路或
&& 短路与
! 逻辑反
&= 逻辑与赋值(赋值的简写形式)
|= 逻辑或赋值(赋值的简写形式)
^= 异或赋值(赋值的简写形式)
== 相等
!= 不相等
?: 三元运算符(IF-THEN-ELSE)

两个boolean类型的数据可以做 == 和 != 的比较,但是不可以做 > ,>= , < , < =运算。boolean类型的不可以和整型或浮点型的数据作比较。

短路逻辑运算符

对于 && 运算,如果左边表达式的值为false,就不在计算右边表达式的值,直接得出为false的结论;
对于 || 运算,如果左边的表达式值为true,就不在计算右边表达式的值,直接得出true的结论。

短路逻辑运算符的应用,如,

if (denom != 0 && num / denom > 10)

防止被0除错误。

赋值运算符

赋值运算符允许你对一连串变量赋值。如,

int x,y,z;
x = y = z = 100; 

括号运算符

圆括号(不管是不是多余的)不会降低你程序的运行速度。因此,添加圆括号可以减少含糊不清,不会对你的程序产生消极影响。

结合关系

例:

int result = 2;
result = (result = result * 2) * 6 * (result = 3 + result);

此处 result 的运算结果是168。即,先计算左边括号里的表达式,再计算右边括号里的表达式。
真正自己编程的时候,这个表达式应该被拆成若干个表达式,然后以明显的正确的顺序来进行计算。如,

int result = 2;
int temp;
int tempTwo;
result = result * 2;
temp = result;
tempTwo = result +3;
result = temp * 6 * tempTwo;
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,670评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,928评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,926评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,238评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,112评论 4 356
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,138评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,545评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,232评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,496评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,596评论 2 310
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,369评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,226评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,600评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,906评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,185评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,516评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,721评论 2 335

推荐阅读更多精彩内容