对应第三章<操作符>、第四章<控制执行流程>、第五章<初始化与清理>、第六章<访问权限控制>
简单梳理java语言的语法。
一 操作符
大部分只能操作基本类型。"=="、"!="、"="和String
类的操作例外。
- 算术操作符。加减乘除。
- 关系操作符。生成
boolean
型结果。对象的"=="比较的是引用,要比较内容需要用equals()
;基本类型的比较用"=="。 - 逻辑操作符
- 常量。指数计数法,在数字末尾加"l"等以表示数据类型。
- 按位操作符。按位与(&)、或(|)、异或(^)、非(~,一元操作符)。
- 移位操作符。左移位(<<,操作数向左移动,低位补0)、右移位(>>,操作数向右移动,为正则高位插0,负则高位插1)、无符号右移位操作符(>>>,高位插0)。
如果对byte
或者short
进行移位赋值运算,它们会先被转成int
类型再移位,可能会被截断。 - 三元操作符。boolean-exp?value0:value1
- 类型转换操作符。(强转)。
1.1 优先级
基本规则先乘除后加减。引入括号后的规则。
1.2 赋值操作符
基本类型的赋值,复制的是值。
对象的赋值,则是将“引用”有一个地方赋值到另一个地方。
在方法中或者作为参数传递时,都要注意引用传递的问题。
class Foo {
int level;
}
class Bar {
public void fooBar() {
Foo f1 = new Foo();
Foo f2 = new Foo();
f1.level = 1;
f2.level = 2;
f1 = f2;
f1.level = 3;//这里会同时改变f1、f2的level值,因为他们指向同一引用
}
public void fooBarParam(Foo f) {
f.level = 4;//会改变外部对象的值
}
}
二 流程控制
if-else等,略。
三 初始化与清理
初始化
- 构造器,默认构造器。
构造器之间可以相互调用,但是只能放在第一行,且只能调用一个。 - 方法重载
重载方法的参数类型提升。如果传入的实参类型小于声明的形参类型,实参的数据类型会被提升。如果char
参数方法未被找到,它会被提升成int
型。 - this关键字
表示“调用方法的那个对象”。
编译器暗中将所操作的对象的引用作为第一个参数传递给方法。
清理
java依靠垃圾回收器清理不需要的对象,释放内存空间,详细的解析可以看《深入解析Java虚拟机》读书笔记。
类中有finalize()
方法,当垃圾回收器准备释放对象时。会先调用finalize()
,并在下一次垃圾回收动作中真正回收对象占用的内存,当然这期间用户可以将其“救活”。
java的垃圾回收器还涉及内存整理的工作。
成员的初始化
- 初始化的时机
类(静态)变量在必要(用到)的时刻(比如调用静态方法,实例化对象)才会初始化为代码中的值。 - 初始化的值
基本数据类型会被初始化为对应类型的标准初值,未赋值的引用类型会被初始化为null
。 - 初始化的顺序
使用到类时:
1.先初始化类变量。
2.按成员变量定义的顺序初始化成员变量。
所有变量都会在构造器被调用前完成初始化。 - 初始化代码的位置
构造器,或者声明处。
数组的初始化
数组有一个固有成员用于标识数组长度。
声明一个数组,相当于持有一个对数组的引用(已经分配空间)。
如果是引用数组,在将对象赋值给引用之后才算初始化完成。
注意初始化数组的几种形式。
String[] array = {"", "'",};//仅能在声明的同时使用
array = new String[]{"", "",};
array=new String[4];
枚举
public enum Spiciness {
NOT, MILD, MEDIUM, HOT, FLAMING
}
枚举类会自动创建toString()
方法,ordinal()
声明标识特定enum的声明顺序,static values()
按照声明顺序产生常量值构成的数组。常用于switch
语句。
四 访问权限控制
4.1 包名的控制
标识本类:包名(package xxx
)
引用外部类:外部引用时是import xxx.xxx.xx;
。
java解释器查找类:类名(命名空间+类名)确定一个类。
.java文件被编译后,每个类都会有输出文件,名称与类名相同,以.class结尾。
- Java解释器的运行过程
找到环境变量CLASSPATH(包含若干目录,用作查找.class文件的根目录);
从根目录开始获取报的名称并将句点替换成反斜杠,以从CLASSPATH根中产生一个路径名称;
当编译器碰到import
语句,会尝试在CLASSPATH指定的目录中查找,然后从已编译的文件中找出对应的.class文件。
4.2 权限标识符的控制
权限标识符有四种权限级别,公开访问public
,保护访问protected
,包访问(默认权限),私有访问private
。
4.3 接口和实现
访问权限的控制常被称为具体实现的隐藏。
为什么要用接口?
将权限的边界划分在数据类型的内部,有两个方面的考虑:
- 在结构中构建自己的内部机制,而不必担心用户会偶然地将内部机制当做是可以使用的接口的一部分;
- 接口与具体实现分离。外部除了接口,不需要了解其他信息。
外部调用应该不依赖于除了public
信息外的任何具体细节。
接口同时提高了可读性。
public方法写在前,protected、private方法写在后,也是一种可以尝试的编码习惯。
4.4 类的访问权限控制
每个编译单元(文件)只允许一个public
类,且名字必须与文件名相同。
文件内允许完全不带public
类。此时可以随意对文件命名,不常用。
4.5 总结
关键字package
、包的命名模式和关键字import
构成包名的控制体系。
访问权限控制专注于类库的创建者与使用者之间的关系,一是为了不让用户触碰到不改触碰的部分;二是允许类的设计者可以放心改变类的具体实现,不必过分担心对外部的影响。