枚举
定义
在Java编程语言中,可以使用enum关键字定义枚举类型。所有的枚举类都继承于java.lang.Enum类。
eg:
//使用enum关键字声明一个枚举类
public enum Day {
//枚举类的值,类型是Day
SUNDAY,//星期天
MONDAY,//星期一
TUESDAY,//星期二
WEDNESDAY,//星期三
THURSDAY,//星期四
FRIDAY,//星期五
SATURDAY//星期六
}
枚举常用的方法
编译器在创建枚举时会自动添加一些特殊方法。
public class Test {
public static void main(String[] args) {
Day d = Day.MONDAY;
//所有的枚举都隐式继承于java.lang.Enum,java.lang.Enum继承于java.lang.Object
System.out.println(d instanceof Object);//true
System.out.println(d instanceof Enum);//true
// 遍历枚举
// 每一个枚举类都有一个静态的values方法,它是编译器加的
// 静态的values方法按照声明的顺序返回一个包含所有枚举值的数组
Day[] arr = Day.values();
for (Day day : arr) {
System.out.println(day);
}
System.out.println("*******************************");
// 静态的valueOf(String)方法,将字符串转换成枚举值,它是编译器加的
Day d1 = Day.valueOf("SUNDAY");// 将字符串SUNDAY转换为Day.SUNDAY
// 枚举值转换为字符串
//toString(),name()是实例方法,继承于java.lang.Enum
System.out.println(d1.name());// 将Day.SUNDAY转换为字符串SUNDAY
System.out.println(d1.toString());// 将Day.SUNDAY转换为字符串SUNDAY
// 获取枚举的序号
System.out.println(Day.SUNDAY.ordinal());// 0
System.out.println(Day.MONDAY.ordinal());// 1
// 枚举的比较
Day m1 = Day.MONDAY;
Day m2 = Day.MONDAY;
System.out.println(m1 == m2);// true
System.out.println(m1.equals(m2));// true
}
}
异常
异常的传播
查看栈的轨迹,method2中抛出的异常传递到method1,然后传递到main。
public class Test{
public static void method1() {
method2();
}
public static void method2() {
String str = null;
str.toString();
}
public static void main(String[] args) {
method1();
}
}
异常处理
因为method2处理了异常,因此异常不再传递给method1。因此method1和main方法将不受method2中异常的任何影响,打印语句将会执行。但是,method2中抛出异常后的语句将不会执行。
public class Test{
public static void method1() {
method2();
System.out.println("method1");
}
public static void method2() {
String str = null;
// 尝试执行try代码块,如果捕获到了NullPointerException,就执行catch块
try {
str.toString();
System.out.println("hello");//不会执行
} catch (NullPointerException e) {
System.out.println("捕获到异常");
}
System.out.println("method2");
}
public static void main(String[] args) {
method1();
System.out.println("main");
}
}
finally的使用
public class Test{
public static void f(Connection con){
try {
con.open();//打开连接
//使用连接做些一个任务
String str = null;
str.toString();
} catch (Exception e) {
System.out.println("捕获到异常信息");
}finally{//不管有没有异常产生,finally块总是会执行
con.close();//关闭连接
}
}
public static void main(String[] args) {
Connection con = new Connection();
f(con);
}
}
异常体系
- Throwable是异常体系的最顶层类。Error(错误)和Exception(异常)继承于Throwable类。
- 程序通常不会捕获或抛出Error。当错误发生时,在代码中没法做任何处理。
- 大多数程序抛出并捕获Exception类派生的对象。
- Exception分为两种:运行时异常(RuntimeException)和受检查异常(CheckedException)。
- RuntimeException和所有继承于RuntimeException的子类称为运行时异常。
- Exception的子类除了运行时异常,其他的都是受检查异常。
- 编译能通过,但是运行时发生的异常是运行时异常, 编译不能通过,需要处理的异常是受检查异常。
public class Test{
public static void f1() {
// NullPointerException是运行时异常,编译时不会提醒需要捕获
String str = null;
str.toString();
}
public static void f2() {
// yyyy-MM-dd
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
//在编译时提醒需要捕获的是受检查异常
try {
Date date = sdf.parse("120dfd");
} catch (ParseException e) {
e.printStackTrace();
}
}
}
运行时异常不需要捕获,因为产生运行时异常是因为代码编写问题,可以通过规范代码(增加条件判断)来避免运行时异常的发生。 受检查异常需要在程序中做处理,因为这是没办法避免的。比如ParseException,转换的字符串可能来自于客户的输入,这个输入是事先无法预期的。
自定义异常
如果需要定义运行时异常,那么需要继承RuntimeException。如果需要定义受检查异常,需要继承Exception。
eg1:运行时异常
public class CurrencyDoNotMatchException extends RuntimeException{
//message代表异常信息
public CurrencyDoNotMatchException(String message) {
super(message);
}
}
eg1:受检查异常
public class CurrencyDoNotMatchException extends Exception{
//message代表异常信息
public CurrencyDoNotMatchException(String message) {
super(message);
}
}