Java语言复习笔记
Java程序设计概述
- Java白皮书关键术语:
- 简单性
- 面向对象
- 分布式
- 健壮性
- 安全性
- 体系结构中立
- 可移植性
- 解释性
- 高性能
- 多线程
- 动态性
即时编译:虚拟机可以选择将执行最频繁的字节码序列转换为机器码。
Java编程环境
-
- JDK(Java开发工具包):程序员编写Java程序时使用的软件
- JRE(Java运行时的环境):用来运行Java程序的工具
Java的基本程序设计结构
-
类名必须以字母开头,后跟数字或字母。
-
- main方法必须声明为public
- 每个Java应用都必须有main方法
- main方法总是静态的
-
整形:
- int 4字节
- short 2字节
- long 8字节
- byte 1字节
长整形数值后缀L或l
十六进制数值前缀0X或0x
八进制数值前缀0
二进制数值前缀0B或0b
Java没有无符号形式的int,long,short,byte
-
浮点类型:
- float 4字节 后缀F或f
- double 8字节 后缀D或d
在十六进制表示法中,p表示指数,尾数用十六进制数表示,指数采用十进制,指数的基数为2。
舍入误差:在二进制系统中无法精确表示分数1/10
-
转义序列:
- \b 退格
- \t 制表
- \r 回车
- \n 换行
- \f 换页
- \s 空格
- \ 仅在文本块中用于连接这一行与下一行
Unicode转义序列会在解析代码之前处理。
-
boolean类型:
- false
- true
整型值与布尔值间不可转换。
-
标识符由字母,数字,货币符号和“标点连接符”组成,第一个字符不能是数字。
不要再自己的代码中使用**$**符号。
必须使用final声明常量。
- 整数被0除将产生一个异常,而浮点数被0除会产生一个无穷大或NaN的结果。
- >>> 运算符会用0填充高位,>> 会用符号位填充高位,不存在 <<< 运算符。
&& 比 || 的优先级高。
- 将一个字符串与一个非字符串拼接时,后者将会转换为字符串。
请使用equals()方法检测两个字符串是否相等,不要使用 == 来检测!== 只能检测两个字符串是否在同一位置上,而相等字符串不一定在同一位置上。
-
空串是长度为0的字符串,内容为空
null表示无任何对象与该变量关联
-
文本块:
以 “”"(三引号) 开头,以 “”" (三引号)结尾,提供跨多行的字符串字面量。
在文本块中,行位的 \ 会把这一行与下一行连接起来。
-
不能在嵌套的两个块中声明两个同名的变量。
-
对于带标签的break语句,标签必须放在想要跳出的最外层循环之前,且必须紧跟一个冒号。
对于带标签的continue语句,将跳转到有匹配标签的循环的首部。
-
int[] a 与 int a[] 均可定义数组a。
允许有长度为0的数组(不是null)。
对象与类
-
对象的三个主要特征:
- 行为
- 状态
- 标识
-
对象变量并不实际包含一个对象,它只是引用一个对象。
-
静态字段属于类,而不属于单个对象。
-
Java程序设计语言总是采用按值调用,方法会得到所有参数的一个副本,方法不能修改传递给它的任何参数变量的内容。
方法不能修改基本数据类型的参数(即数值或布尔值)。
方法可以改变对象参数的状态。
方法不能让一个对象参数引用一个新对象。
-
方法的签名:方法名,参数类型。
-
字段默认值:
- 数值:0
- 布尔值:false
- 对象引用:null
方法中的局部变量必须明确的初始化。
-
record:记录,是一种特殊形式的类,其状态不可变,且公共可读。
记录的实例字段自动为final字段。
记录相较于类更易读,更高效,且在并发程序中更安全。
继承
-
Java中的所有继承都是公共继承。
-
不能扩展记录,记录也不能扩展其它类。
-
调用构造器的语句只能作为另一个构造器的第一条语句出现。
-
在覆盖一个方法时,子类方法不能低于超累方法的可见性。
-
final类不可继承
final方法不可覆盖
final字段不可改变
final类中的方法自动成为final,不包括字段
枚举和记录总是final。
-
访问控制修饰符:
- private:仅本类可访问
- public:外部可访问
- protected:本包和所有子类可访问
- 无:默认本包中可访问
-
在比较两个包装器对象时调用equals方法
绝对不要依赖包装性的同一性
不要将包装器对象作为锁
不要使用包装器类构造器
包含在包装器中的信息不可变 -
包含抽象(abstract)方法的类本身必须被声明为抽象的。
抽象类不能实例化,但可以引用非抽象子类的对象。
-
比较枚举类型的值时,可用 == 来比较。
枚举的构造器总是私有的。
- 同一个包中的所有类都可以访问protected字段,而不论它们是否为这个类的子类。
接口,Lambda表达式与内部类
- 接口不是类,而是对希望符合这个接口的类的一组需求。
- 接口中的所有方法都自动是public方法,所以不必在接口中声明方法时提供关键字public。
- 接口绝不会有实例字段,但可以包含常量。
- 实现接口时,必须把方法声明为public。
- 接口中的字段总是public static final。
- 记录和枚举不能扩展其他类,但可以实现接口。
- 接口可以是密封的(sealed),与密封类一样,直接子类型必须在permits字句中声明,或放在同一个源文件中。
- 可为任何接口方法提供一个默认实现,必须有default修饰符标记该方法。
- 类似于Lambda表达式,方法引用也不是一个对象,不过为一个类型为函数式接口的变量赋值时会生成一个对象。
- 只有当Lambda表达式的体只调用一个方法而不做其它操作时,才能把Lambda表达式重写为方法引用。
- Lambda表达式3个部分:
- 一个代码块
- 参数
- 自由变量的值:指非参数且不在代码中定义的变量
- Lambda表达式的数据结构必须存储自由变量的值。
- 在Java中,Lambda表达式就是闭包。
- Lambda表达式可以捕获外围作用域中变量的值,只能引用值不会改变的变量。
Lambda表达式中捕获的变量必须是事实最终变量。
Lambda表达式的体与嵌套块有相同的作用域。
-
内部类声明的所有静态字段都必须是final,并初始化为一个编译时常量,内部类不能有static方法。
-
声明局部变量时不能有访问说明符,其作用域总是限定在声明这个局部类的块中。
-
局部类不仅可访问外部类的字段,还可访问局部变量(事实最终变量)
-
匿名内部类不能有构造器。
-
静态内部类可以有静态字段和方法
在接口中声明的内部类自动是static和public
类中声明的接口,记录,枚举自动为static。
异常,断言,日志
-
如果在子类中覆盖了超类的一个方法,子类方法生命的检查类型不能比超类更通用。
-
不管是否捕获到异常,finally子句中的代码都会执行
如果finally块也有一个return语句,这个返回值将会遮蔽原来的返回值。
-
finally子句的体要用于清理资源,不要把改变控制流的语句放到finally子句中。
-
未被任何变量引用的日志记录器可能会被垃圾回收,所以应该用静态变量存储其引用。
泛型程序设计
- Java类库使用变量U表示集合的元素类型,K和V分别表示表的键和值的类型,T,U,S表示任意类型。
- Java泛型的限制:
- 不能用基本类型实例化类型参数
- 运行时类型查询只适用于原始类型
- 不能创建参数化类型的数组
- 带有类型变量的静态字段和方法是完全非法的。
- 既不能抛出也不能捕获泛型类的对象,泛型类扩展Throwable也是非法的。
集合
- 可以认为Java迭代器位于两个元素之间,当调用next时,迭代器就越过下一个元素,并返回刚越过的元素的引用。
- Iterator接口的remove方法会删除上次调用next方法返回的元素,调用remove前没有调用next方法是不合法的,必须先调用next越过要删除的元素。
- 在调用next后,remove方法会删除迭代器左侧的元素,如果调用了previous,则会删除迭代器右侧的元素。而且不能连续两次调用remove。
- LinkedList对象不会缓存位置信息,所以查询操作效率很低。
- 需要一个动态数组时,若需多线程同步操作则用Vector,否则用ArrayList。
并发
- 不要调用Thread类或者Runable对象的run方法。直接调用run方法只会在同一个线程中执行这个任务,而没有启动新的线程,应调用Thread.start方法,这会创建一个新县城来执行run方法。
- 线程状态:
- New(新建)
- Runable(可运行)
- Blocked(阻塞)
- Waiting(等待)
- Timed waiting(记时等待)
- Terminated(终止)
- 在任何给定时刻,一个可运行的线程可能正在运行也可能没有运行。
- 死锁现象:如果其他所有线程都被阻塞,最后一个活动线程调用了await方法但没有先解除另外某个线程的阻塞,现在这个线程也会阻塞,程序会永远挂起。
- 只有线程拥有一个条件的锁时,他才能在这个条件上调用await方法,signalAll或signal方法。