Java编程思想学习笔记三:操作符
2018-03-21 09:32
741 查看
一、更简单的打印语句
在第二章中使用了一个打印语句如下:System.out.println("Hello World");结合上一篇学习static的文章可知,打印语句如果在一个类中多次调用的时候,我们可以把这个语句抽出来写成静态方法,然后通过导入静态包的方式调用这个打印方法。
test包下的Printer类:
package com.chenxyt.java.test; public class Printer { public static void print(String msg){ System.out.println(msg); } }practice包下的TestStatic类:
package com.chenxyt.java.practice;
import static com.chenxyt.java.test.Printer.*;
public class TestStatic{
public static void main(String[] args) {
print("This is TestStatic");
}
}
二、使用Java操作符
Java与其他语言一样,支持加号,正号,减号,负号,乘除号等操作符,同时“=”,“==”和“!=”不光可以操作基本操作类型,还可以操作所有的对象。此外,String类支持“+”和“+=”。三、优先级
当一个表达式中存在多个操作符时,操作符的优先级就尤为重要了,它决定了程序运算操作执行的先后顺序。Java中的计算顺序与其它语言的基本相同,先计算乘除,再计算加减,有括号的先计算括号里边的。System.out.println()语句中包含“+”的操作符号,简单的只是进行字符串的连接,复杂一点的就是当编译器发现“+”前边是一个String类型,会尝试将“+”后面的内容转换成String类型。四、赋值
赋值操作使用的是“=”操作符,将“=”右边的值赋给左边,右值可以是任意的常数、变量或者是表达式,只有它能生成一个值即可,而左值必须是一个明确的已命名的变量,就是必须要有个物理空间来进行存储。比如,可以将一个常数赋给变量a=4;但是却不能将一个变量赋值给一个常数
4=a;对于基本的数据类型,赋值操作没有引用的涉及,只是单纯的将一个值赋值给另一个值。例如a=b,当b再次被修改时,a不会受到影响,因为a与b相互独立。但是对于对对象的赋值来说,情况却大大不同,因为我们对对象的操作是操作了对象的引用,所以当一个对象赋值给另一个对象时,实际上是拷贝了引用到左值,也就是比如c和d是指向两个不同对象的引用,当c=d时,实际发生的情况是c和d都指向了原本只有d指向的对象。而c被赋值之后,原来的引用丢失了,它曾经所指向的不再被引用的对象被垃圾回收器回收了。如下例子创建了两个不同的对象,进行赋值操作。
package com.chenxyt.java.practice;
class Tank{
int level;
}
public class CopyTest{
public static void main(String[] args) {
Tank tk1 = new Tank();
Tank tk2 = new Tank();
tk1.level = 2;
tk2.level = 3;
System.out.println("tk1.level = " + tk1.level + "---tk2.level = " + tk2.level);
tk1=tk2;
System.out.println("tk1.level = " + tk1.level + "---tk2.level = " + tk2.level);
tk2.level=5;
System.out.println("tk1.level = " + tk1.level + "---tk2.level = " + tk2.level);
}
}运行结果如下:
tk1和tk2分别是两个独立的对象,它们内部有level属性,赋值之前两个对象的属性值不同,赋值操作完成之后两个对象的属性值相同,当再次更改对象tk2的level值时,预期的理想情况是不会影响tk1的值,但实际结果并非如此,tk1与tk2对象的属性相同,这与前面的分析结果相同。 Java中这种针对对象的特殊现象叫做“别名现象”,如果想避免这种现象的话,可以使用如下操作,赋值操作针对属性而不是对象的引用
tk1.level=tk2.level这样操作就可以保持两个对象本身相互独立。
在调用方法传参的时候也是会产生“别名问题”,如下例子,调用方法copy之后,理想的是只改变了方法内的值,实际上是改变了方法之外对象的值。
package com.chenxyt.java.practice; class Tank{ int level; } public class CopyTest{ public static void copy(Tank tk3){ tk3.level = 9; } public static void main(String[] args) { Tank tk1 = new Tank(); tk1.level = 2; System.out.println("tk1.level = " + tk1.level); copy(tk1); System.out.println("tk1.level = " + tk1.level); } }运行结果,方法外部tk1对象的值被修改了
五、算术操作符
Java中的算术操作符与其它语言基本类似,有加号(+)、减号(-)、乘号(*)、取整(/)、取余(%),同时也具有简化运算符的功能如要将x加4之后再赋值给x,则可以写成:x+=4;
六、自动递增和递减
Java中的递增递减操作与其它语言基本类似,递增符合(++),递减符合(--),操作目的是快速使一个整数加1或者减1如a++等同于a=a+1,这两种符号分别有两种使用方式称为“前缀式”和“后缀式”,前缀式意味着符号在变量前边,后缀式意味着符号在变量后边。二者的区别,对于前缀式是先做运算再取值,如a=1,b=++a,此时a跟b的值都是2,而后缀式则是先取值再做运算,如a=1,b=a++,此时b的值为1,a的值为2。七、关系操作符
关系操作符生成的是一个boolean(布尔)结果,它们计算操作数之间的关系,如果关系为真则结果为true,如果关系为假则结果为false。关系操作符号包括小于(<)、大于(>)、小于等于(<=)、大于等于(>=)、等于(==)以及不等于(!=)。等于和不等于适用于所有的基本数据类型,而其它的操作符不适用于boolean类型,因为它们的值为true或者false,比较大小没有意义。 操作符“==”和“!=”同样适用于操作对象,但是与基本操作类型相比有一些不同。package com.chenxyt.java.practice; public class OperationTest{ public static void main(String[] args) { Integer itg1 = new Integer(22); Integer itg2 = new Integer(22); System.out.println(itg1==itg2); System.out.println(itg1!=itg2); int int1 = 22; int int2 = 22; System.out.println(int1==int2); System.out.println(int1!=int2); } }如上创建了两个Integer对象和两个int基本数据类型值,分别做“==”和“!=”判断,结果如下:
从结果可见,两个对象是“!=”,而两个int基本数据类型值是“==”,这是为什么呢?因为对于对象来说,“==”和“!=”比较的是对象的引用,虽然这两个对象的值相同,但是他们对象的引用并不是一个,也就是他们在内存中有两个不同的存储位置,所以不相同。所以要想比较对象的值是否相同,我们可以使用对象的equals()方法来进行比较,它是Object类的一个通用方法,第一章中说到过所有类的父类都是Object,因此任何类的对象都可以调用这个方法。
package com.chenxyt.java.practice; public class OperationTest{ public static void main(String[] args) { Integer itg1 = new Integer(22); Integer itg2 = new Integer(22); System.out.println(itg1.equals(itg2)); } }结果如下:
新的问题来了,我们看如下示例,我们自定义了一个新的类,创建了两个对象进行比较:
package com.chenxyt.java.practice; class Oper{ int i; } public class OperationTest{ public static void main(String[] args) { Oper op1 = new Oper(); Oper op2 = new Oper(); op1.i=2; op2.i=2; System.out.println(op1.equals(op2)); } }结果如下:
结果仍然为fasle!这是为什么呢?这是因为Object类中equals()方法实际上是比较两个引用是否相同,就是它与“==”的本质效果是一样的,但是在第一个示例中的Integer类中,Java覆盖了这个方法,方法内容判断两个对象的类型是否相同以及值是否相同即可。而我们自己创建的Oper类并没有覆盖这个方法,所以沿用的还是
ae8d
Object类的方法。常见的String类也是覆盖了equals()方法,效果与Integer类的对象相同。
八、逻辑操作符
Java中的逻辑操作符与其它语言基本类似,包括与(&&)、或(||)、非(!),不同的是Java中的逻辑操作符只能应用与布尔值之间或者是表达式结果为布尔值。package com.chenxyt.java.practice; public class OperationTest{ public static void main(String[] args) { int a = 1; int b = 2; int c = 3; System.out.println((a>b)&&(b>c)); System.out.println((a>b)||(b<c)); System.out.println(!(a<b)); } }运算结果如下:
逻辑运算满足如下关系,“&&”逻辑与运算符必须两边同时为真则结果为真,否则为假。“||”逻辑或运算符只要有一边为真则结果为真,“!”非运算符取对应值的对立面,即非真则假。对于逻辑与和逻辑或运算还有个名词叫做短路,即当两个算式做逻辑与运算时,如果左边第一个算式为假,则显然这个逻辑表达式最后的结果一定为假,那么就没有必要进行下边的表达式计算,直接结束运算,这个过程称作短路。
九、直接常量
Java中同样可以使用例如“π”这种常量表示。十、按位操作符
Java中的按位操作符与其他语言基本相似,有按位与(&)、按位或(|)、按位异或(^)和按位非(~)操作符。它们针对基本数据类型的一个比特位(bit)进行运算。运算规则如下,&操作符必须同时为1才为1,|操作符只有同时为0时才为0,^操作符只要有一个为1就为1,~是单目运算符,取反,若值为1则结果为0,反之为1。按位操作符除了~还可以与“=”合起来使用,如&=或者|=、^=。 对于布尔值,同样可以进行按位与、按位或和按位异或运算,但是不能进行按位非运算,并且他们不会被短路,不管第一个表达式结果是什么,都会继续运算下去。十一、移位操作符
移位操作符操作的也是二进制的“位”,移位操作符只能用来处理整数类型。移位操作也是二元操作符,一共有三种,左移操作符(<<),右移操作符(>>),无符号右移操作符(>>>),左移操作符是操作符左边的数向左移动操作符右边指定的位数,低位补0,右移操作符是操作符左边的数向右移动操作符右边指定的位数,其中正数高位补0,负数高位补1。无符号右移操作符是Java独有的一种,即不管正数还是负数,右移之后高位都补0。关于移位操作有两点说明,一是高位指的是左边的位,二是对于int类型,最大长度为32位,对于long类型最大长度为64位。移位示例如下:package com.chenxyt.java.practice; public class OperationTest{ public static void main(String[] args) { int a = 6297; int b = -6297; System.out.println(Integer.toBinaryString(a)); System.out.println(Integer.toBinaryString(b)); System.out.println(Integer.toBinaryString(a>>5)); System.out.println(Integer.toBinaryString(a<<5)); System.out.println(Integer.toBinaryString(a>>>5)); System.out.println(Integer.toBinaryString(b>>5)); System.out.println(Integer.toBinaryString(b<<5)); System.out.println(Integer.toBinaryString(b>>>5)); } }我们以int类型6297为例,分别对正6297和负6297做三种位移操作,结果如下:
满足前边所说,左移低位补0,右移正数高位补0,低位补1,因为高位0没有实际意义,所以没有写出。同时,因为数据类型为int类型,所以最大长度为32位,超出的部分被截断了。
如果对char、short、byte类型的数值进行移位处理,那么他们会被先转成int类型,并且得到的结果也只是int类型。只有数值右端对的低5位才会有用,这样可以防止移位得到超过int类型的最大位数。比如说5<<34,因为最多能移32位,所以要把34转成二进制,然后取低5位,34转换成2进制是100010,取低5位就是00010,也就是5<<34实际上就是5<<2=10100=20。同样的对于long类型,long的最大长度为64位,所以数值的低6位有效。移位运算符同时也支持“<<=”等运算操作。
十二、三元操作符IF-ELSE
三元操作符也称条件操作符,它有三个操作符。表达形式如下: boolean-exp?value1:value2; boolean-exp是一个布尔表达值,如果值为真,则返回value1的值,如果值为假,则返回value2的值。如:package com.chenxyt.java.practice;public class OperationTest{
public static void main(String[] args) {
int a = 5;
int b = a>10?a*100:a*10;
System.out.println("b===="+ b);
}
}运行结果:
因为a<10,所以布尔表达式的值为假,所以取value2也就是a*10的值。
十三、字符串操作符+和+=
Java中可以使用+和+=连接String类型,并且当操作符左边你的数为String时,Java会试图将操作符右边的类型转换成String。十四、使用操作符常犯的错误
注意“=”和“==”的区别,以及逻辑运算符如(&&)和位运算符(&)的区别和前自增“++i”和后自增“i++”的区别。注意“==”和“equals()”的使用,注意别名现象。十五、类型转换操作符
Java中有跟其它语言相同的转换方式,(类型)值形式,也可以使用基本类型的包装器的转换方法进行转换。十六、Java没有size of
C语言中使用size of来获取程序占用的内存字节大小,目的是确定平台的移植操作,Java中没有这个方法,也就是不需要获取这个值,因为Java在不同的平台下基本数据类型具有相同的大小,可以便捷的移植。十七、总结
操作符在各个语言中基本通用,熟练掌握自增自减、逻辑运算、位运算以及移位操作即可,理解“==”和“equals()”的原理,理解别名现象。相关文章推荐
- [Java编程思想-学习笔记]第3章 操作符
- java 编程思想的学习笔记 - 第三章 操作符 第四章 控制执行
- Java 编程思想(第四版)学习笔记(3)操作符
- Java 编程思想(第四版)学习笔记(8)多态
- Java 编程思想(第四版)学习笔记(5)初始化与清理
- java编程思想学习易错点笔记一
- Java 编程思想(第四版)学习笔记(6)访问权限控制
- [Java编程思想-学习笔记]第1章 对象导论
- [Java编程思想-学习笔记]第2章 一切都是对象
- 【学习笔记⑧】JAVA编程思想学习笔记
- Java编程思想学习笔记——枚举、注解
- 【Java编程思想--学习笔记(一)】访问控制-包
- java编程思想学习笔记 第七章 复用类
- 【java编程思想--学习笔记(二)】访问控制-Java访问权限修饰词
- java编程思想学习笔记:如何选择继承与组合
- 【学习笔记】JAva编程思想之多态
- JAVA编程思想学习笔记(二)
- java编程思想 学习笔记 equals 与==
- java编程思想学习笔记(二)
- Thinking in Java [Java编程机制] 学习笔记 -- 操作符Operator