Thinking in Java 学习手记 第3章 操作符
在最底层,Java中的数据是通过使用操作符来操作的。
1、使用Java操作符
(1)操作符接受一个或多个参数,并生产一个新值。参数的形式和普通方法调用不同,但效果是相同的。
(2)操作符作用于操作数,生成一个新值,有时也会改变操作数自身的值。
(3)几乎所有的操作数都只能操作“基本类型”。例外的操作符是“=”、“==”、“!=”,这些操作符几乎可以操作所有对象。另外,String类还支持“+”和“+=”。
2、优先级
(1)最简单的操作符优先级是先乘除后加减。
(2)其他的优先级往往很难记忆,所以应该用括号明确规定计算顺序。
(3)在加法表达式中存在字符串时,加法表达式中其他类型的对象会自动调用toString()方法转化成字符串。
3、赋值
(1)“=”对基本类型进行赋值操作时,把右边的值赋值给左边(副本赋值)。
(2)“=”对对象进行操作时,实际上是将对象的引用进行了赋值,而没有复制对象。下面这个例子说明这一点。
//: operators/Assignment.java
// Assignment with objects is a bit tricky.
package operators;
class Tank {
int level;
}
public class Assignment {
public static void main(String[] args) {
Tank t1 = new Tank();
Tank t2 = new Tank();
t1.level = 9;
t2.level = 47;
System.out.println("1: t1.level: " + t1.level +", t2.level: " + t2.level);
t1 = t2;
System.out.println("2: t1.level: " + t1.level + ", t2.level: " + t2.level);
t1.level = 27;
System.out.println("3: t1.level: " + t1.level + ", t2.level: " + t2.level);
}
} /* Output:
1: t1.level: 9, t2.level: 47
2: t1.level: 47, t2.level: 47
3: t1.level: 27, t2.level: 27
*///:~
(3)对象作为方法的参数时,传递进入方法的是对象的引用,在方法中对象发生改变,实际就是方法之外的那个对象发生了改变。
//: operators/PassObject.java
// Passing objects to methods may not be
// what you're used to.
package operators;
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';
System.out.println("1: x.c: " + x.c);
f(x);
System.out.println("2: x.c: " + x.c);
}
} /* Output:
1: x.c: a
2: x.c: z
*///:~
4、算术操作符
(1)Java中的算术运算符包括加号(+)、减号(-)、除号(/)、乘号(*)以及模运算(%)。
(2)用操作符后面紧跟一个等号,运算的同时将结果赋值给第一个操作数。只要有实际意义,就可用。
(3)一元加减操作符(正负号),会将较小的数据类型提升为int。
5、自动递增和递减
(1)“++”和“--”,前缀时先加减后引用,后缀时先引用后加减。例如:
//: operators/AutoInc.java
// Demonstrates the ++ and -- operators.
package operators;
public class AutoInc {
public static void main(String[] args) {
int i = 1;
System.out.println("i : " + i);
System.out.println("++i : " + ++i); // Pre-increment
System.out.println("i++ : " + i++); // Post-increment
System.out.println("i : " + i);
System.out.println("--i : " + --i); // Pre-decrement
System.out.println("i-- : " + i--); // Post-decrement
System.out.println("i : " + i);
}
} /* Output:
i : 1
++i : 2
i++ : 2
i : 3
--i : 2
i-- : 2
i : 1
*///:~
6、关系操作符
(1)Java中关系运算符包括小于(<)、大于(>)、大于或等于(>=)、小于或等于(<=)、不等于(!=)、等于(==)。
(2)上面这些操作符除了等于和不等于,可以适用于所有的基本数据类型。
(3)等于和不等于适用于boolean之外的所有数据类型。
(4)等于和不等于也适用于对象之间,比较对象的引用。
(5)equal()方法默认比较的是对象的引用。
7、逻辑操作符
(1)逻辑操作符有与(&&)、或(||)、非(!)。
(2)逻辑操作符的操作数只接受boolean型。
//: operators/Bool.java
// Relational and logical operators.
package operators;
import java.util.*;
public class Bool {
public static void main(String[] args) {
Random rand = new Random(47);
int i = rand.nextInt(100);
int j = rand.nextInt(100);
System.out.println("i = " + i);
System.out.println("j = " + j);
System.out.println("i > j is " + (i > j));
System.out.println("i < j is " + (i < j));
System.out.println("i >= j is " + (i >= j));
System.out.println("i <= j is " + (i <= j));
System.out.println("i == j is " + (i == j));
System.out.println("i != j is " + (i != j));
// Treating an int as a boolean is not legal Java:
//! System.out.println("i && j is " + (i && j));
//! System.out.println("i || j is " + (i || j));
//! System.out.println("!i is " + !i);
System.out.println("(i < 10) && (j < 10) is "
+ ((i < 10) && (j < 10)) );
System.out.println("(i < 10) || (j < 10) is "
+ ((i < 10) || (j < 10)) );
}
} /* Output:
i = 58
j = 55
i > j is true
i < j is false
i >= j is true
i <= j is false
i == j is false
i != j is true
(i < 10) && (j < 10) is false
(i < 10) || (j < 10) is false
*///:~
(3)当使用操作符时,一旦能够确定整个表达式的值,就不在计算剩下的部分了,这种现象称之为短路。
8、直接常量
(1)直接常量后面的后缀字符标志了它的类型:
①L代表long
②F代表float
③D代表double
(2)十六进制由0x为前缀
(3)八进制由0为前缀
( 4)Integer和Long类有静态方法toBinaryString(),可将数字转化成二进制输出。
9、按位操作符
(1)按位操作符包括与(&)、或(|)、非(~)、异或(^)。
(2)以上按位操作符除非(~)之外,都可以与等号(=)连用。
10、移位操作符
(1)移位操作符包括左移(<<)、(有符号)右移(>>)、 无符号右移(>>>)
(2) 左移(<<)在右方插入0。
(3) (有符号)右移(>>),若符号为正,则在高位插入0,否则在高位插入1。
(4) 无符号右移(>>>),无论正负,都在高位插入0。
(5)“移位”可以和“等号”组合使用。
11、三元操作符
(1)操作符形式Boolean-exp ? value0 : value1
(2)如果boolean-exp的值为true,计算value0的值;若boolean值为false,计算value1的值。计算结果作为操作符最终产生的值。
13、类型转换操作符
(1)转型允许拓展转型,不允许窄化转型
(2)不允许不相干的类的对象之间相互转型
(3)对于基本数据类型,转型时,使用截尾转型。
(4)如果要使用舍入转型,需调用java.lang.Math.round()
(5)不同的数据类型之间进行运算,数据类型会自动提升
----------------解决方案--------------------------------------------------------