java
程序退出
try {
System.exit(0);
} finally {
System.out.println("finally");
}
这种情况下,不会进入finally块.
序列化(Serializable)
序列化条件
实现Serializable
接口
什么时候需要序列化?
- 想把对象保存到文件或数据库
- 用socket在网络上传输
- 通过RMI传输对象
序列化前与序列化后对象的关系
深复制,反序列化后对象的地址与原地址不同.
注意
- static,transient后的变量不会被序列化
- 父类序列化后,子类自动序列化
- 当对象实例引用了其它对象,则引用对象也会被序列化
clone
默认clone()方法是浅复制而非深复制
assert
断言
开启
默认不开启,需要添加-enableassertions
或-ea
来开启
用法
- assert
- assert
:<错误信息表达式>错误信息表达式>
java程序运行过程
java源代码(.java) -(编译器)-> 字节码(.class) -(java虚拟机)-> 运行
包含native code的是虚拟机而非字节码,在不同操作系统上装不同的java虚拟机,但字节码是一样的不用变,因此java可以跨平台
java平台
组成:
- java虚拟机
- java API
java优点
- 快速开始
- 写更少的代码
- 写更好的代码
- 开发得更快
- 避免平台相关性代码
- 一次编写,到处运行
注意
- 组合优于继承
死锁
如何避免?
- 避免嵌套封锁(十分重要,是
完全的解决之道
,如果存在嵌套封锁,即使当前检查过代码未发现死锁情况,但后面却可能因代码的添加而造成死锁,因此每次添加加锁的代码就需要检查一次死锁,会造成十分繁重的负担!) - 只对有请求的进行封锁
- 避免无限期的等待(虽然可以避免程序停止崩溃,但仍会造成卡顿,因此只是起到预防作用,而非解决之道)
初始化顺序
- 父类
- 静态代码块
- 代码块与成员字段
- 构造方法
比如实例化一个类生成对象, 首先是加载类,类加载后会执行静态代码块, 然后实例化生成一个对象,执行代码块与成员字段与构造方法.
不论加载类还是执行代码,都是父类优先,同一个类内,会先执行代码块与成员字段再执行构造方法(即使代码块或成员字段写在构造方法后面),多个代码块与成员字段按代码中的顺序执行
变量
定义
一般变量的定义可包含以下(有序)内容:
- 访问修饰符
- 变量类型
- 变量名
变量类型
- 实例变量(非静态变量): 属于具体实例(对象)的变量
- 类变量(静态变量): 属于类的变量
- 局部变量
- 方法变量
命名与约定
java变量名允许字母
,数字
,$
,_
,不能以数字开头
变量名不能是关键字或保留字
但从约定上来说,$
是给一些自动生成的代码用的,_
只推荐用在大写常量名连接上,如NUM_GEARS
任意数量参数varargs
方法参数可以使用varargs,如run(int a, int... b)
值传递与引用传递
原始类型是按值传递的,其它是按引用传递的
异常
分类
- 检查性异常,无法预见的,编译时无法忽略
- 运行时异常,可以避免的,编译时可以忽略
- 错误,在程序处理范围之外
结构
Throwable:
- Error
- Exception
- RuntimeException (不需要捕获)
- 其它Exception (需要捕获)
表达式
表达式由变量,操作符,方法调用组成.
表达式执行的顺序可以用括号()来改变.
语句块
表示式可以分为:
- 表达式语句
- 赋值
- ++与–
- 方法调用
- 对象创建
- 定义语句
- 定义变量
- 控制流语句
- 选择
- if then
- if then else
- switch * 循环
- for
- while
- do while * 分支
- break
- continue
- return
语句块由大括号{}包围,任何可以放置单个语句的地方都能放置语句块
其它
- 整数溢出问题: 如将天数转换为毫秒时可能需要强制转换为long型
- null与”“需要正确地进行考虑.
- 数据库操作如xxx like ‘%%’并非相当于无限制,当数据为null时则不会取到
- 注意有些ScheduledExecutorService会吞异常,就是抛出异常没有显示就自动停止计时器了,不要被坑!!!
- 粗略地计算过socket的延时,大致结果如下(也就是说,阿里云同主机情况下,就算游戏服务器这种对速度要求很高的,也基本上能满足):
- 本地: 0.04ms
- 阿里云同主机(实例系列二的): 0.02ms
- 阿里云同地域不同主机: 0.2ms