操作符
1.优先级
当表达式中存在多个操作符时,操作符的优先级就决定了各部分的计算顺序
优先级 | 操作符 | 说明 |
---|---|---|
1 | () | 小括号 |
2 | [] | 中括号 |
3 | + - | 正负号 |
4 | ++ -- ! | 自增 自减 非 |
5 | * / % | 乘除,取余 |
6 | + - | 加减 |
7 | << >> >>> | 移位运算符 |
8 | > >= < <= | 大小关系 |
9 | == != | 相等关系 |
10 | & | 按位与 |
11 | ^ | 按位异或 |
12 | | | 按位或 |
13 | && | 逻辑与 |
14 | || | 逻辑或 |
15 | ?: | 条件运算 |
16 | = += -= *= /= %= | 赋值运算 |
17 | &= |= <<= >>= >>>= | 位赋值运算 |
2.赋值
使用操作符
=
取右边的值(即右值),复制给左边(即左值)
右值可以是任何常数,变量或表达式,但左值必须是一个明确的已命名的变量
别名现象:当为对象"赋值"时,真正操作的是对对象的引用.
//避免方式:引用对象的具体属性
t1.level = t2.level;
方法调用中的别名问题
书中例子:
class Letter {
char c;
}
public class PassObject {
static void f(Letter y) {
y.c = 'z';
}
public static void main(String[] args) {
Letter x = new Letter();
x.c = 'a';
print("1: x.c: " + x.c);
f(x);
print("2: x.c: " + x.c);
}
}
Output:
1: x.c: a
2: x.c: z
3.算数运算符
加号(+),减号(-),除号(/),乘号(*),取模操作符(%,从整数除法中产生余数)
x+=4
简写:要将x加4,并将结果赋回x.
练习4
public class ExerciseVelocity4 {
public static void main(String[] args) {
//速度=路程/时间
float d = 565.3f;
float t = 3.6f;
System.out.println("路程: " + d);
System.out.println("时间: " + t);
float v = VelocityCalculator.velocity(d, t);
System.out.println("速度: " + v);
}
}
class VelocityCalculator {
/**
* 公式:速度=路程/时间
* @param d 路程
* @param t 时间
* @return 速度
*/
static float velocity (float d, float t) {
if(t == 0) return 0f;
else return d/t;
}
}
一元加,减操作符
一元减号用于转变数据的符号,
而一元加号只是为了与一元减号相对应,
但是它唯一的作用仅仅是将较小类型的操作数提升为int。
public class OneYuan {
public static void main(String[] args) {
//定义一个byte类型变量
byte b = 1;
//用一元加号后赋值给c,发现报错。
byte c = +b;
//再赋值给整型变量d后能编译通过,证明b编程了int型。
int d = +b;
}
}
4.自动递增递减
递增
++
:增加一个单位
递减--
:减少一个单位
使用方式:
前缀式
:先执行计算,再生成值
后缀式
:先生成值,再执行计算
5.关系运算符
产生的是Boolean结果
关系运算符包括(大于 >
大于等于 >=
小于 <
小于等于 <=
等于 ==
不等于 !=
)
关系操作符==
和!=
适用于所有object对象
测试对象的等阶性
==
和!=
操作符只能用于判断两个比较对象是否属于同一个引用- 特殊方法
equals
比较对象的实际内容是否相同(不适用基本类型)
class Value {
int i;
}
public class EqualsMethod {
public static void main(String[] args) {
Integer n1 = new Integer(47);
Integer n2 = new Integer(47);
System.out.println(n1 == n2);
System.out.println(n1 != n2);
Value v1 = new Value();
Value v2 = new Value();
v1.i = v2.i = 100;
System.out.println(n1 .equals(n2 ));
}
}
/* Output:
* false
* true
* false
*/
因为
equals()
方法默认比较引用,所以必须重写覆盖默认equals()
方法
总结:
==操作符
既可以用于比较基本的数据类型,也可以用于比较对象,而equals只可以用于对象之间的比较- 在比较String类型的对象时,==操作符的原理只有两个变量是同一对象的引用时才会返回true,而equals方法只要两个变量的内容相同则返回true
- 对象进行比较时,equals方法默认的原理是判断两者的内存地址是否相同,所以默认情况下与
==
操作符返回的结果相同,但是这里应该发现差别,也就是equals方法可以被重写—用户可以定制自己的equals方法,而==
操作符不能被重写
6.逻辑操作符
与 &&
或 ||
非 !
生成结果是一个Boolean
值
//模拟扔硬币
public class ExerciseCoinToss7 {
public static void main(String[] args) {
Random random = new Random();
int coin = random.nextInt();
if(coin % 2 == 0)
System.out.println("正面");
else
System.out.println("反面");
}
}
短路
- 一旦能够明确无误地确定整个表达式的值,就不再计算表达式余下部分
7.直接常量
- 十六进制适用于所有整数数据类型,以前缀
0X
,后面跟0~9或a~f
大小写不敏感 - 八进制由前缀
0
后缀0~7
- 基本类型通过静态方法
toBinaryString()
来显示二进制
指数计数法
- Java采用了一种很不直观的记数法(
e
)来表示指数 e
指10的幂次
示例
1.39e10 == 1.39 X 1010
8.按位操作符
public class BinaryExercise10 {
public static void main(String[] args) {
int i = 1 + 4 + 16 + 64;
int j = 2 + 8 + 32 + 128;
System.out.println("i = " + Integer.toBinaryString(i));
System.out.println("j = " + Integer.toBinaryString(j));
System.out.println("i & j = " + Integer.toBinaryString(i & j));
System.out.println("i | j = " + Integer.toBinaryString(i | j));
System.out.println("i ^ j = " + Integer.toBinaryString(i ^ j));
System.out.println("~i = " + Integer.toBinaryString(~i));
System.out.println("~j = " + Integer.toBinaryString(~j));
}
}
/**
* 输出:
* i = 1010101
* j = 10101010
* i & j = 0
* i | j = 11111111
* i ^ j = 11111111
* ~i = 11111111111111111111111110101010
* ~j = 11111111111111111111111101010101
*/
独特的布尔类型:
- 用来操作整数基本数据类型的单个
bit
(二进制位) - 对两个参数中对应的位执行布尔
Boolean
运算 - 具有和
逻辑操作符
相同效果,但是按位操作符不会短路
- 不能执行按位
非
^
- 按位操作符新增
异或
~
- 移位表达式中不能使用布尔运算
9.移位运算符
- 运算对象也是二进制的
位
- 只可以用来处理整数类型
- 对
char
byte
short
进行操作会被转成int
类型,结果也是int
类型
public class BitManipulation {
public static void main(String[] args) {
Random rand = new Random(47);
int i = rand.nextInt();
int j = rand.nextInt();
printBinaryInt("-1", -1);
printBinaryInt("+1", +1);
int maxpos = 2147483647;
printBinaryInt("maxpos", maxpos);
int maxneg = -2147483648;
printBinaryInt("maxneg", maxneg);
printBinaryInt("i", i);
printBinaryInt("~i", ~i);
printBinaryInt("-i", -i);
printBinaryInt("j", j);
printBinaryInt("i & j", i & j);
printBinaryInt("i | j", i | j);
printBinaryInt("i ^ j", i ^ j);
printBinaryInt("i << 5", i << 5);
printBinaryInt("i >> 5", i >> 5);
printBinaryInt("(~i) >> 5", (~i) >> 5);
printBinaryInt("i >>> 5", i >>> 5);
printBinaryInt("(~i) >>> 5", (~i) >>> 5);
long l = rand.nextLong();
long m = rand.nextLong();
printBinaryLong("-1L", -1L);
printBinaryLong("+1L", +1L);
long ll = 9223372036854775807L;
printBinaryLong("maxpos", ll);
long lln = -9223372036854775808L;
printBinaryLong("maxneg", lln);
printBinaryLong("l", l);
printBinaryLong("~l", ~l);
printBinaryLong("-l", -l);
printBinaryLong("m", m);
printBinaryLong("l & m", l & m);
printBinaryLong("l | m", l | m);
printBinaryLong("l ^ m", l ^ m);
printBinaryLong("l << 5", l << 5);
printBinaryLong("l >> 5", l >> 5);
printBinaryLong("(~l) >> 5", (~l) >> 5);
printBinaryLong("l >>> 5", l >>> 5);
printBinaryLong("(~l) >>> 5", (~l) >>> 5);
}
static void printBinaryInt(String s, int i) {
System.out.println(s + ", int: " + i + ", binary:\n " +
Integer.toBinaryString(i));
}
static void printBinaryLong(String s, long l) {
System.out.println(s + ", long: " + l + ", binary:\n " +
Long.toBinaryString(l));
}
} /* Output:
-1, int: -1, binary:
11111111111111111111111111111111
+1, int: 1, binary:
1
maxpos, int: 2147483647, binary:
1111111111111111111111111111111
maxneg, int: -2147483648, binary:
10000000000000000000000000000000
i, int: -1172028779, binary:
10111010001001000100001010010101
~i, int: 1172028778, binary:
1000101110110111011110101101010
-i, int: 1172028779, binary:
1000101110110111011110101101011
j, int: 1717241110, binary:
1100110010110110000010100010110
i & j, int: 570425364, binary:
100010000000000000000000010100
i | j, int: -25213033, binary:
11111110011111110100011110010111
i ^ j, int: -595638397, binary:
11011100011111110100011110000011
i << 5, int: 1149784736, binary:
1000100100010000101001010100000
i >> 5, int: -36625900, binary:
11111101110100010010001000010100
(~i) >> 5, int: 36625899, binary:
10001011101101110111101011
i >>> 5, int: 97591828, binary:
101110100010010001000010100
(~i) >>> 5, int: 36625899, binary:
10001011101101110111101011
...
*///:~
10.三元操作符 和 字符串操作符
三元操作符
if-else
boolean-exp ? value1 : value1
如果布尔表达式为true,就计算value0,如果为false,就计算value1。
字符串操作符 (
+
+=
)
用来连接不同的字符串
11.类型转换操作符
- 窄化转换(将能容纳更多信息的数据转换成无法容纳那么多信息的类型),就有可能面临数据丢失的危险,编译器会
强制
我们进行类型转换 - 扩展转换.不必显式地进行类型转换,因为新的类型一定能容纳原来类型的信息,不会造成信息丢失.
- 布尔类型不允许进行任何转换
1.结尾和舍入
- java.lang.Math的
round()
方法 - 遵循四舍五入
2.提升
前提 : 对基本数据类型执行算术运算或按位运算
char
,byte
,short
自动转换成int
- 表达式中最大的数据类型决定表达式最终结果的数据类型