第十一章 异常、断言、日志
- 方法应该在其首部声明所有可能抛出可检查(
Checked Exception
)异常,如
public FileImputStream(String name) throws FileNotFoundException
否则必须在方法中try catch
住,由内部处理
- 一个方法必须声明所有可能抛出的已检查异常(如
IOException
),而未检查异常要么是不可控制(Error
),要么就应该避免发生(RuntimeException
)
解析:
- 粉红色的是受检查的异常(checked exceptions),其必须被 try{}catch语句块所捕获,或者在方法签名里通过throws子句声明.受检查的异常必须在编译时被捕捉处理,命名为 Checked Exception 是因为Java编译器要进行检查,Java虚拟机也要进行检查,以确保这个规则得到遵守.
- 绿色的异常是运行时异常(runtime exceptions),需要程序员自己分析代码决定是否捕获和处理,比如 空指针,被0除...
- 而声明为Error的,则属于严重错误,如系统崩溃、虚拟机错误、动态链接失败等,这些错误无法恢复或者不可能捕捉,将导致应用程序中断,Error不需要捕捉。
- 子类中的异常要比超类中的异常更具体
- 方法抛出一个异常例子
int max( int [] arr )
{
throw new EOFException();
}
- 异常如果不是自己利用
try catch
捕获和处理就throw
给调用者处理 -
assert x>=0: "x>=0"
冒号后边的String
时传递给AssertionError
对象的信息用于显示在控制台上 - 断言只用在开发和测试阶段,当代码发布时,这些插入的检测语句将会被自动移走。
- 不要捕获Java类库中定义的继承自
RuntimeException
的运行时异常类,如:IndexOutOfBoundsException / NullPointerException
,这类异常由程序员预检查来规避,保证程序健壮性。
第十二章 泛型
- 定义简单的泛型类,如
public class Pair <T,U> { ... }
- 泛型方法,如
class ArrayAlg
{
public static <T> T getMiddle( T [] a)
{
return a.[a.length/2];
}
}
- 类型变量的限定
public static <T extends Comparable> T min(T[] a) //也可以用 T extends Comparable & Serializable
- 泛型的约束与局限性
不能用基本类型实例化类型参数,例如没有Pair<int>
只有Pair<Integer>
运行时检查只检查原始类型,例如
Pair<String> str;
Pair<Employee> emp;
str.getClass() == emp.getClass()`//为true
不能创建泛型的数组,例如没有Pair<String>[] str = new
Pair<String>[10]
;但声明是合法的
不能用new
实例化类型变量,例如没有new T(...)
不能在静态域和方法中使用类型变量
既不能抛出也不能捕获泛型类对象,泛型类不能扩展Throwable
Pair<Employee>
和Pair<Manager>
是两个无关的类(虽然Manager
继承Employee
)带有超类型限定的通配符(
Pair<? super Employee>
)可以向泛型对象写入
带有子类型限定的通配符(Pair<? extends Employee>
)可以从泛型对象读取Java中的泛型基本上都是在编译器这个层次来实现的。在生成的Java字节码中是不包含泛型中的类型信息的。==使用泛型的时候加上的类型参数,会在编译器在编译的时候去掉。这个过程就称为类型擦除==
所以如下的两个方法在编译时会报错,因为编译后两个方法的字节码相同,是同一个方法的重复定义而不是重载。
void test(List<String>){};
void test(List<Integer>){};