前言
之前有零散地阅读过TIJ,但是都是针对自己的问题去有针对性的阅读,没有从头梳理过Java的一些基础知识。从前段时间开始自己也开始了整体性地学习TIJ的过程,也从这篇博客开始把自己的一些感悟和理解总结起来,也希望能对大家和我自己都有些帮助。
第二章 一切都是对象
第一章大致都是一些面向对象语言或针对JAVA的特性的一些介绍,在后面的每一章中都有详细的介绍,所以从读书总结从第二张开始。
2.1 用引用操作对象
- 对于Java对象,操作的标识符都是引用,且引用可脱离对象单独存在。
- 如果向未指向对象的引用发送消息,那么会返回一个运行时错误 -->动态绑定机制。
2.2 对象存储
2.2.1 JVM的存储分区
对于这一块,JVM的内存模型是必须要清楚的内容,这个博客对于JVM内存模型的介绍非常全面,可以参考学习。
简略的说,内存可以分为虚拟机栈,本地方法栈,程序计数器,堆,方法区(包含运行时常量池)等部分。
2.2.2 基本类型
Java在任何平台上每种基本类型所占空间的大小都一致,这也是Java跨平台特性的原因之一。
参考2.2.1中可知,java基本类型不存储在堆中,而基本类型对饮的包装类的实例对象存储在堆中,java提供了自动包装机制来处理基本类型和实例对象的转换问题。
特别的是:基本类型的包装类和String类都是final的,不可变,所以每次操作都会生成一个新的对象,看起来和基本类型的传值操作很相似。
且String类在初始化时JVM针对其初始化的方式的不同会有不同的处理,后面专门讲解String的章节会详细介绍。
2.3 对象作用域
java中主要是用花括号来控制作用范围。
基本类型的作用域:
{
int x = 12;
/* only x available */
{
int q = 96;
/* both x & q available */
}
/* only x available */
/* q “out of scope” */
}
而下面的方式是不允许的,在C++中是可以的,但在Java中是不被允许的。
{
int x = 12;
{
int x = 96; /* illegal */
}
}
对象的作用域:
new的对象可以存活在作用域之外,只要有引用一直指向它,那么对象就不会消失,但在范围外引用会失效。
2.4 类
2.4.1 成员变量初始化
类的成员变量在实例化时会自动初始化,在没有指定的情况下,基本类型会初始化成为默认值,类对象会设置成为null。
-
但是局部变量不会设置默认初始值!需要自己初始化,如果忘记了,那么在编译时会范围错误。类型 值 Boolean false Boolean false char false Boolean '\u0000'(null) byte (byte)0 short (short)0 int 0 long 0L float 0F double 0D
p.s. 这里初始化的问题在后面类的初始化和加载的时候会详细讨论,涉及继承,多态等情况时,初始化会变得较为复杂。
2.8 注释和嵌入式文档
在注释内按照标准的格式输入,可以利用JavaDoc提取文档。
独立文档标签是一些@开头的命令。
- @see引用其他类,可以和@author,@version一起使用
- @docRoot产生到根目录的相对路径
- @link,@inheritDoc,@Param等等
2.9 编码风格
- 驼峰风格,Java标准。
- java代码一般都是摆放开,闭花括号的方式。
第三章 操作符
3.1
静态导入:其实很好理解,和普通import的区别就在于静态导入后使用对应类的静态方法时不需要使用类名.静态方法的方式,可以直接使用方法名。但其实我个人认为一般用import就可以了,因为静态方法多的时候,使用静态import一旦出现重名的情况很容易发生冲突。
3.7 equals和==
这是java里令人很迷惑的部分,可以参考17章的笔记~
3.8 逻辑操作符
- 在java中,只有boolean值可以作为判断语句的参数,和C语言不一样可以用0和其他值的区别来判断。
- String + boolean,此时boolean也会被转型成为String。
3.10 按位操作符
- 与&,或|,非~,异或^
- Boolean可以与,或,异或,但是不可以按位非(非是0,1间切换)
3.11 移位操作符
- 左移:左移位运算符(<<)能将运算符左边的运算对象向左移动运算符右侧指定的位数(在低位补0)。
- 右移:有符号”右移位运算符(>>)则将运算符左边的运算对象向右移动运算符右侧指定的位数。“有符号”右移位运算符使用了“符号扩展”:若值为正,则在高位插入0;若值为负,则在高位插入1。Java也添加了一种“无符号”右移位运算符(>>>),它使用了“零扩展”:无论正负,都在高位插入0。这一运算符是C或C++没有的。这一点很重要!
对char, byte, short类型的数值进行移位处理,在移位进行之前,会被转换成int类型,并且最终也会得到int。
类型转换
基本类型的类型转换中,窄化转换必须要强制类型转换,但是扩展转换不需要显示的类型转换。
布尔类型不支持类型转换!
截尾与舍入
- 从高的基本类型转为低的时,会采用截尾操作
- 如果想从float,double到int用舍入操作,那么可以用Math.round()。
- Java中对int型进行任何操作时,都会容易出现溢出的情况,必须要留意(Java不会提示你超过范围了)。
第四章 控制执行流程
4.7 java goto
goto在C,C++中是不推荐使用的,在java中没有goto关键字,java通过另一种加了限定的方式实现了受控的goto。
label1:
//外部循环
{
//内部循环
{
//...
break; //1
//...
continue; //2
//...
continue label1; //3
//...
break label1; //4
}
}
上面伪代码中如果执行到3处,那么会跳转到循环外label1处继续进行迭代;
如果进行到4出那么会跳转到label1处,并且不会重新进入迭代。
总结
前三章相对来说都是非常基础的内容,在之前的工作中基本都已经熟悉了。但是有几点需要注意:
- JVM的内存模型和GC的过程,这个需要专门的学习,后面也会重新看一下深入JVM的书籍,上学的时候看感觉不怎么能看得懂,现在值得重新学习一波。在日常工作中使用JAVA感觉理解Java底层的工作原理真的会有很大的帮助;
- String类型在Java里是一种非常特殊的类型,需要好好专门学习学习。