操作符
1,使用java操作符
操作符接受一个或多个参数,并生成一个新值。参数的形式与普通的方法调用不用,但是效果是相同的。加号和一元的正号(+)、减号和一元的负号(-)、乘号(*)、除号(/)以及赋值号(=)的用法与其他编程语言类似。
操作符作用于操作数,生成一个新值。另外,有些操作符可能会改变操作数自身的值,这被称为“副作用”。那些能改变其操作数的操作符,最普通的用途就是用来产生副作用;但是要记住,使用此类操作符生成的值,与使用没有副作用的操作符生成的值,没有什么区别。
几乎所有的操作符都只能操作“基本类型”。例外的操作符是“=”、“==”和“!=”,这些操作符能操作所有的对象。除此之外,String类支持“+”和“+=”。
2,优先级
在表达式中,操作符的优先级决定了运算顺序。java对计算顺序做了特别的规定,其中,最简单的规则就是先乘除后加减。但是有时候,表达式略微复杂时,仅靠这个规则可读性不是很强,所以应该用括号明确计算的顺序。
public class Precedence{ public static void main(String[] args){ int x = 1, y = 2, z = 3; int a = x+y-2/2+z; int b = x+(y-2)/(2+z); System.out.println("a= "+a+",b= "+b); } }
上述的带括号和没有括号的运算,结果是不一样的,而且,带有括号的可读性更好。
3,赋值
赋值使用的操作符是(=)。它的意思是“取右边的值,把它复制给左边”。右值可以是任何常数、变量或者表达式。但是左值必须是一个明确的、已命名的变量。也就是说,必须有一个物理空间可以存储等号右边的值。比如:
a = 4;
不能把任何东西赋给一个常数,常数不能作为左值(4 = a就是错误的)。但是a = b是可以的,就是将b的内容复制给a,当a再发生变化时,b不受影响。
赋值中会有一个特殊的现象——“别名现象”,是java操作对象的一种基本方式。
class Tank{ int level; } public class Assignment{ public static void main(String[] args){ Tank t1 = new Tank(); Tank t2 = new Tank(); t1.level = 10; t2.level =20; 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 = 30; System.out.println("3:t1.level: "+t1.level+",t2.level: "+t2.level); } } Output: 1:t1.level:10,t2.level:20 2:t1.level:20,t2.level:20 3:t1.level:30,t1.level:30
1,2两个输出应该没有问题,但是3的输出或许和想象中的有点不同,t2没有经过更改,怎么随着t1的更改而更改了。这是因为赋值操作的是一个对象引用,当t1 = t2时,他们指向的是相同的对象。这就是“别名现象”。
要想避免“别名现象”,可以这样赋值:
t1.level = t2.level;
这样可以保持两个对象彼此独立。
4,算术操作符
java的基本算术操作符与其他大多数程序设计语言是相同的。其中包括加号(+)、减号(-)、除号(/)、乘号(*)及其取模操作符(%,它从整数除法中产生余数)。整数除法会直接去掉结果的小数位,而不是四舍五入的结果。
5,自动递增和递减
递增和递减运算是两种相当不错的快捷运算。其中递减操作符是“--”,意为减少一个单位;递增操作符是“++”,意为“增加一个单位”。比如,a 是一个int类型的整数,那么++a就等价于(a=a+1)。
递增和递减有两种使用方式,通常称为“前缀式”和“后缀式”。对于前缀递增和前缀递减(++a或--a),会先执行运算,再生成值。对于后缀递增和后缀递减(a++或a--),会先生成值,再执行运算。例:
public class AutoInt{ 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); } } Output: i:1 ++i:2 i++:2 i:3 --i:2 i--:2 i:1
6,关系操作符
关系操作符生成一个boolean(布尔)结果,它们计算的是操作数的值之间的关系。如果关系是真实的,关系表达式会生产true(真);如果关系不真实,则生成false(假)。关系操作符包括(<)、大于(>)、小于或等于(<=)、大于或等于(>=)、等于(==)以及不等于(!=)。等于和不等于适用于所有的基本数据类型,而其他比较符不适用于boolean类型。因为boolean值只能为true或false,“大于”和“小于”没有意义。
public class Equivalence{ public static void main(String[] args){ Integer n1 = new Integer(10); Integer n2 = new Integer(10); System.out.println(n1 == n2); System.out.println(n1 != n2); } } Output: false true
上述例子可以看出,对于引用类型的比较,和基本数据类型不一样。因为引用类型比较的是其对象的地址,n1 和 n2所指向的地址是不一样的,所以n1 == n2 是不正确的,返回false。对于引用类型的比较,应该用equals。例如:n1.equals(n2); 这样返回的结果就是:true。
7,逻辑操作符
逻辑操作符“与”(&&)、“或”(||)、“非”(!)能根据参数的逻辑关系,生成一个布尔值。
public class Bool{ public static void main(String[] args){ int i = 10; int j = 20; System.out.println(((i>5)&&(j<30))); System.out.println(((i>15)&&(j<30))); System.out.println(((i>15)||(j<30))); System.out.println((i != j)); } } Output: true false true true
8,按位操作符
按位操作符用来操作整数基本数据类型中的单个“比特”(bit),即二进制位。按位操作符会对两个参数中对应的位执行布尔代数运算,并产生一个结果。
如果两个输入位都是1,则按位“与”操作符(&)生成一个输出位1;否则生一个输出位0。如果两个输入位只要有一个是1,则按位“或”操作符(|)生成一个输出位1;只有两个输入位都是0的情况下,产生一个输出位0。如果输入位的某一个是1,但不全是1,那么按位“异或”操作(^)生成一个输出位1。按位“非”(~),也称为取反操作符,它属于一元操作符,只对一个操作数进行操作(其他按位操作符都是二元操作符)。按位“非”生成与输入位相反的值——若输入0,则输出1;若输入1,则输出0。