12.17 Java基础15
- 昨日知识点回顾
public static void main(String[] args) {
// Error 错误 ->不可挽救,通过异常处理无法解决.
// OutOfMemoryError StackOverflowError
// F4
// Object->Throwable->Exception
// Object->Throwable->Error
// Exception 异常
// - 运行时异常 RuntimeException
// - 检查异常 simple.parse
// F4 Object->Throwable->Exception->RuntimeException->NullPointerException
// NullPointerException
// ParseException
// 异常处理方式1 抛出异常,我不处理,谁调用我谁处理,一直向上抛,最终抛给虚拟机
// try...catch捕捉异常,处理。
}
- 异常处理剩余部分
- 掌握异常的处理-捕获异常try...catch...finally
- 把所有可能抛出异常的,或者肯定抛出异常的代码都写到try代码块中;catch语句紧随try语句后,用来捕获异常并进行处理;
- 结构:
try{
可能抛出异常的代码块;
}catch(异常类型 变量名){
处理异常的代码;
}
抛出异常--》捕获异常--》捕获失败(当catch的异常类型与抛出异常类型不匹配时,捕获失败 )/捕获成功(当catch的异常类型与抛出的异常类型匹配时,捕获成功) --》异常(未)被处理,程序中断(继续)运行。
若没有抛出异常,则运行时会跳过catch代码块。
- catch语句里都写什么代码?
可以写任意需要对异常进行处理的代码;
可以调用异常对象的方法,例如printStackTrace,查看异常发生的栈轨迹。
System.out.println(e.getMessage());可以在控制台打印异常详细信息。
注意:catch部分有一个给程序员看 e.printStackTrace(); ->保存到日志文件中
输出或者返回一个字符串,给客户看 System.out.println(e.getMessage());
相关代码:
public class Person {
private int age;
public int getAge() {
return age;
}
public void setAge(int age) {
if(age<1) {
throw new RuntimeException("年龄不能小于1。");//括号里的内容就相当于getMessage()
}
this.age=age;
}
}
- 多catch捕获
catch语句的异常类型必须从子类到父类的顺序,否则编译错误;异常只要被成功捕获一次,就被处理了,不会再继续抛出了。
相关代码:
public static void main(String[] args) {
try {
System.out.println("start");
String str = null;
System.out.println(str.length());
System.out.println(1 / 0);
System.out.println("end");
} catch (ArithmeticException | NullPointerException ex) { //运用了逻辑或
System.out.println("ex :" + ex.getMessage());
} finally {
// 这里是释放资源 [不管是否发生异常,都会执行]
System.out.println("finally");
}
}
- finally块
一般用于资源的清理和释放工作。如:关闭已打开的文件、删除临时文件、释放数据库连接。
再比如:IO[finally 流关闭 ].JDBC.[资源释放]
finally{
不管什么情况,一定被执行的代码块;
}
- try catch finally的搭配
必须有try,catch可以有1个或多个,finally最多1个,也可以没有;
还有另外一种组合:只有try和finally,没有catch。如果try块中抛出了异常,则肯定不能被捕获,程序中断,但是finally代码块依然会被执行。
- 异常的层层抛出
- throw关键字在方法体中使用
throw 异常对象;
例如:
throw new Exception();
或者
catch(Exception e){
throw e;
}
运行时异常是JVM自动抛出,非运行时异常需要程序员用throw关键字抛出;由于抛出了Exception,是非运行时异常,所以编译期检测,要求必须处理,处理的方式有两种:
使用try/catch/finally进行处理;不处理,用throws声明异常。而当用throw抛出异常后,基本都使用throws进行声明!
throws用在方法声明处,声明该方法可能发生的异常类型;一个方法如果使用了throws,那么调用该方法时,编译器会提醒必须处理这些异常,否则编译错误;throws后可以声明多种类型,用逗号隔开即可;而抽象方法也可以使用throws声明该方法可能抛出的异常类型。
如果希望对异常先统一处理,可以处理后再抛出,调用的时候可以继续处理。
- 了解finally与return和System类的exit方法
- try,catch,finally顺序
在try中没有异常的情况下try、catch、finally的执行顺序 try --- finally
如果try中有异常,执行顺序是try --- catch --- finally
如果try中没有异常并且try中有return这时候正常执行顺序是try ---- finally --- return
如果try中有异常并且try中有return这时候正常执行顺序是try----catch---finally--- return
如果try有异常,相应catch中有return,顺序是try---catch---finally---return
总之 finally 永远执行!除非前面有System.exit(0)退出虚拟机
相关代码:
- System类的exit方法
当try中有异常时,在catch中加System.exit(1);--->(退出虚拟机的方法)
当try中没有异常时加System.exit(1);--->(退出虚拟机的方法)
System.exit(参数);
参数: 0 或 1 都代表退出虚拟机
0:正常退出
1:非正常退出
相关代码:
public static void main(String[] args) {
for (int i = 0; i < 1000; i++) {
if (i == 100) {
System.exit(1);
}
System.out.println(i);
}
System.out.println("over");
}
- 自定义异常
为了能够标记项目中的异常事件,需要使用throw抛出异常;而如果抛出的是API中的标准异常,那么很可能与API中方法抛出的异常混淆,因此需要自定义异常,对团队合作非常有意义。
一般自定义异常类中不写其他方法,只重载必要的构造方法。
相关代码:(找一个运行时异常的子类异常,把它的方法全部复制,粘贴到我们新建的自定义异常类中,相当于我们的自定义异常重写了运行时异常的方法,由此使这个自定义异常和之前的子类异常成为同级)
/**
* 自定义异常 继承RuntimeException
*
* @author Administrator
*
*/
public class MyException extends RuntimeException {
/**
* Constructs a {@code MyException} with no detail message.
*/
public MyException() {
super();
}
/**
* Constructs a {@code MyException} with the specified detail message.
*
* @param s the detail message.
*/
public MyException(String s) {
super(s);
}
}
综合代码:
public static void main(String[] args) {
System.out.println(t1());
System.out.println(t2());
System.out.println(t3());
System.out.println(t4());
}
public static int t1() {
try {
return 1;//1
} catch (Exception e) {
// TODO: handle exception
return 2;
} finally {
}
}
public static int t2() {
try {
return 1;
} catch (Exception e) {
// TODO: handle exception
return 2;
} finally {
return 3;// 特例,finally一定会执行 3
}
}
public static int t3() {
int n = 1;
try {
System.out.println(n/0);
return ++n;//不运行
} catch (Exception e) {
// TODO: handle exception
return ++n;
} finally {
return ++n;// 特例,finally一定会执行 3
}
}
public static int t4() {
try {
return 1;
} catch (Exception e) {
// TODO: handle exception
return 2;
} finally {
return 3;//特例,finally一定会执行
}
//return 4;//编译错误
}
- 断言
JDK1.4版本开始,增加了断言机制;
断言用来进行调试,不在生产环境中使用;
断言使用关键字assert表示,语法非常简单,有两种形式:
assert <布尔表达式>
assert <布尔表达式> : <错误信息>
当布尔表达式的值是true时,忽略assert;
当布尔表达式的值是false时,发生AssertionError错误,程序中断;如果用第二种形式,同时显示错误信息。
- 断言的开启方法
Eclipse默认没有开启断言功能,要使用需要开启。
Window->Preferences->Java->Installed JREs
选中安装的一个JRE->Edit JRE->在默认VM参数框输入-ea->finish->apply and close 由此开启断言
相关代码:
public static void main(String[] args) {
t2(null);
}
public static void t2(String str) {
assert str != null : "字符串不能为null";
System.out.println(str.length());
}
运行得到:Exception in thread "main" java.lang.AssertionError: 字符串不能为null 报断言错误
感想:总体不难。非要说难点,那就在于对try...catch...finally结构的运行结果的仔细判断。
(Ps:今年好多基金经理离职。。唉,钱亚风云离职没多久,周应波大概率也要离职了,又要转换。。)
21:53:13 2021-12-19
posted on 2021-12-19 21:58 heyiyang1312 阅读(5) 评论(0) 收藏 举报
浙公网安备 33010602011771号