使用java操作符
所谓的操作符食指接受一个或多个参数,并生成一个新的值。参数的形式与普通的方法调用不同,但效果是相同的。
加号(+),减号(-),乘号(*),除号(/)以及赋值号(=)
几乎所有的操作符都只能操作‘基本类型’,例外的操作符是“=”,“==”,“!=”,这些操作符能操作所有的对象,除此之外,String类支持“+”和“+=”。
优先级
最简单的规则:先乘除再加减,另外括号优先。
在本章中,笔者只会写一些特殊的操作符以及容易混的操作符,像普通的加减乘除 大于小于 这种基本的 不会描述
赋值
赋值使用操作符“=”
1 对于基本数据类型的赋值很简单。基本类型存储了实际的数据,而并非指向一个对象的引用,所以在赋值的时候很简单,直接将内容赋值到另一个地方,不会影响到原来的。下面演示一个实例
public class Test {
public static void main(String[] args) {
int a = 10;
int b = a;
b = 20;
System.out.println(a);
System.out.println(b);
}
}
本例中 int b = a; 这行代码就是将a的内容赋值给了b,然后紧接着 b = 20;对b进行了修改。但是从打印结果来看,原先的a根本没有收到影响!
2 但是在为对象“赋值”的时候,情况发生了变化。对一个对象进行操作时,我们真正操作的是对象的引用。倘若“将一个对象赋值给另一个对象”,实际是将“引用”从一个地方复制到另一个地方。
public class Test {
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);
}
}
class Tank {
int level;
}
对每个Tank类对象的level都赋予了一个不同的值,然后将t2赋给t1,接着修改了t1。由于赋值操作的是对象的引用,所以修改t1的同时也修改了t2! 这是因为t1和t2包含的是相同引用,指向相同的对象。(原本t1包含的对对象的引用是一个指向值为9的对象。在 t1 = t2 这行代码中,t1的引用被覆盖了,也就是丢失了;而原先值为9的对象,也会被垃圾回收器回收)
自动递增和递减 i++,++i,i-- ,--i
这种通常被称为“前缀式”和“后缀式”。
对于“前缀式”(++a,--a),会先执行计算,在生成值。而对于后缀式(a++,a--),会先生成值,在执行计算。
下面一个例子演示下
public class Test {
public static void main(String[] args) {
int i = 1;
System.out.println("i : " + i);
System.out.println("++i : " + ++i);
System.out.println("i++ : " + i++);
System.out.println("i : " + i);
System.out.println("--i : " + --i);
System.out.println("i-- : " + i--);
System.out.println("i : " + i);
}
}
测试对象的等价性
“==”,“!=”在对基本类型的使用没什么好说的,但是对对象的使用,还是可以聊聊的“
关系操作符“==”,“!=”可适用与所有对象
public class Equivalence {
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);
}
}
读者可能认为输出结果先是true,再试false,因为两个对象都是相同的,但是尽管对象的内容是相同的然而对象的引用确实不同的,而“==”,“!=”比较的就是对象的引用。所以输出结果先是false,再是true。
如果想要比较两个对象的内容是否相同呢?此时,必须使用所有对象都适用的特殊方法equals()。但这个方法不适用于“基本类型”,基本类型直接使用“==”和“!=”即可下面一个例子说明
public class EqualsMethod {
public static void main(String[] args) {
Integer n1 = new Integer(47);
Integer n2 = new Integer(47);
System.out.println(n1.equals(n2));
}
}
但是如果是我们自己创建的类呢,就想下面这样的:
class Value {
int i;
}
public class EqualsMethod2 {
public static void main(String[] args) {
Value v1 = new Value();
Value v2 = new Value();
v1.i = 100;
v2.i = 100;
System.out.println(v1.equals(v2));
}
}
咦?怎么会是false呢?这是因为equals()的默认是比较引用(大家可以看下Object的equals()方法),除非在自己的类中覆盖equals()方法,否则比较的都是引用。
上面的两个Integer类型对象用equals()可以比较内容,就是因为Integer类已经重写了equals()方法。
后面的第17章节,会介绍如果恰当的定义equals()方法。
逻辑操作符
& 所有的都做检查,&&前面的不成立,后面的不在检查。
字符串操作符 +和+=
public class StringOperators {
public static void main(String[] args) {
int x = 0, y = 1, z = 2;
String s = "x, y, z ";
print(s + x + y + z);
print(x + " " + s);
s += "(summed) = ";
print(s + (x + y + z));
print("" + x);
}
private static void print(String s) {
System.out.println(s);
}
}
从打印来看,如果表达式以一个字符串起头,那么后续的所有操作都是字符串的。
结尾和舍入
public class CastingNumbers {
public static void main(String[] args) {
double above = 0.7, below = 0.4;
float fabove = 0.7f, fbelow = 0.4f;
print("(int)above: " + (int)above);
print("(int)below: " + (int)below);
print("(int)fabove: " + (int)fabove);
print("(int)fbelow: " + (int)fbelow);
}
private static void print(String s) {
System.out.println(s);
}
}
通过打印结果我们可以看到,将float或double转换为int类型时候,总是对数字执行截尾,如果想要得到四舍五入的结果,就需要使用java.lang.Math中的round()方法
public class RoundingNumbers {
public static void main(String[] args) {
double above = 0.7, below = 0.4;
float fabove = 0.7f, fbelow = 0.4f;
print("Math.round(above): " + Math.round(above));
print("Math.round(below): " + Math.round(below));
print("Math.round(fabove): " + Math.round(fabove));
print("Math.round(fbelow): " + Math.round(fbelow));
}
private static void print(String s) {
System.out.println(s);
}
}