本文是阅读《Thingking in Java》第三、四、五、六章的总结,包含了Java操作符,流程控制,初始化和清理以及访问权限控制,只记录一些我认为不那么容易理解知识点。
操作符
在Java中操作符有很多,整理如下:
操作符 | 含义 |
---|---|
= | 赋值 |
+ | 加,或一元运算符正号 |
- | 减,或一元运算符减号 |
* | 乘 |
/ | 除,除数不能为0 |
+=、-=、*=、/= | 加减乘除后赋值 |
++ | 自动递增 |
– | 自动递减 |
> | 是否大于 |
< | 是否小于 |
== | 是否等于 |
!= | 是否不等于 |
>= | 是否大于等于 |
<= | 是否小于等于 |
&& | 逻辑与,判断到一个表达式或变量为false,就中断整个判断表达式,并返回false |
|| | 逻辑或,判断到一个表达式或变量为true,就中断整个判断表达式,并返回true |
! | 逻辑非 |
& | 按位与,两个数都是1才是1,其他都是0 |
| | 按位或,两个都是0才是0,其他都是1 |
^ | 异或,两个相同为1,不同为0 |
~ | 按位非,取反,1变成0,0变成1 |
&=、|=、^= | 按位与或异或后赋值 |
<< | 左移 |
>> | 有符号右移,右移的数是正时,在高位插入0,是负数时,在高位插入1 |
>>> | 无符号右移,都在高位插入0 |
<<= | 左移后赋值 |
>>= | 有符号右移后赋值 |
>>>= | 无符号右移后赋值 |
boolean-exp ? val0 : val1 | 三元操作符,boolean-exp为true就返回val0,否则返回val1 |
注意:
- 两个数相乘,数比较大时,可能会溢出,变为0
- 类型转换时可能会丢失数据信息,比如小数转整数,超过int大小的long类型的数转int
控制流程
包含的关键字包括:
关键字 | 含义 |
---|---|
if-else | 判断表达式,else不是必须的 |
while | 循环 |
do-while | 循环,先执行后判断 |
for | 循环 |
return | 退出方法 |
break | 退出循环 |
continue | 继续下一次循环 |
switch | 选择 |
解释可能有不当之处,请见谅指正。
对于循环而言for和while其实差不多,使用看个人习惯,其中对于break和continue在带有标签的情况下,一般用于双重循环,例子如下:
1 | private static void labelLoop() { |
总结如下:
- 一般的continue会退回到内层循环的开头
- 带标签的continue会达到标签的位置,并重新进入紧接着的循环
- 一般的break会退出当前循环
- 带标签的break会退出标签所指的循环
初始化和清理
对于基本类型的初始化比较简单,首先即使不赋值也会有一个默认值,对于对象不赋值则为null,如何去初始化更好可参考我的另一篇总结的文章Java对象的创建和销毁
其中在清理是,需要注意的是finalize方法和垃圾回收机制。
finalize方法
在Java中,对象可能不被垃圾回收,垃圾回收也不等于c++中的析构函数,并且垃圾回收只和内存有关。所以对于finalize方法的使用要谨慎,不要乱用,正常使用Java创建的对象都不需要使用finalize方法去清理,只有包含c或c++语言中创建对象分配内存时,才可以使用finalize方法,调用c或c++的本地方法去清理。当然还有一种情况就是为了保证安全,找出问题,使用时也一定需要调用super.finalize()。
但有时候也需要手动去清理对象,比如类中包含了另一个类时,需要在以后都不用的时候去把引用置为null。
垃圾回收机制
- 标记清除法:首先标记出需要清除的对象,标记完成后再清除,主要缺点是效率不高容易产生大量不连续的内存碎片;
- 标记整理法:在标记清除法的基础上执行完后,再将未被清除的对象移向一端并更新其引用,主要缺点在于移动成本较高,好处是不会产生大量内存碎片;
- 复制算法:将内存分为两个区域,每次只使用一块,用完一块后,使用标记清除法后将还存活的对象复制到另一块去,然后清除这一块的内存,这样就可以了,优点实现简单运行高效,缺点内存缩小为一半;
- 分代收集算法:分为年轻代和老年代,年轻代分为eden和survival,在年轻代中每次回收,会有大量对象被回收,然后就用复制算法完成搜集,在老年代中直接使用标记清除或标记整理算法来清除即可。
对于标记的过程是在对象的引用栈中去遍历,通过某条路径能找到的对象都标记上,在清除时发现未被标记的就清除。
初始化顺序
经过观察发现对于类的初始化顺序总结如下:
父类静态变量>子类静态变量>父类变量>父类构造函数>子类变量>子类构造函数
触发条件:静态变量只要该类被用到就会初始化;普通变量需要创建实例;父类构造函数如果子类没有调用则默认调用的构造函数;同一个类中同一级别的调用顺序和代码顺序有关。
上述中的静态变量和普通变量都是值在申明时就赋值的。
访问权限控制
包含的关键字有:
关键字 | 含义 |
---|---|
private | 只有当前类可以访问 |
protected | 当前类和子类可以访问 |
public | 所有位置都可以访问 |
缺省 | 默认包,在同一个包内,可以当作public来看,在其他包内就当作private来看 |
import | 使用非同一个包内的类时,需要引用类的完全限定名,对于静态方法和字段可采用静态引用,即import static packageName.className; |
以上的关键字都可作用于类以及类的字段和方法上,在开发中,对于接口固定,内部调用的实现方法可作为private,以保证版本控制时,内部实现改变但是使用方法不变,利于程序的维护,也可以讲不想被用户使用到的代码隐藏起来不被直接调用。