目录
心情感悟
写完的博客没保存上,重新写一下,心情忘了,但是作业真的难!!
重点归纳
1.常见的异常
2.throw、throws、try...catch、finally关键字及用法
3.异常链
4.自定义异常及使用
5.运行期异常
知识点记录
异常处理
1.下标越界
2.空指针
3.类型转换异常
4.数字格式化
5.算数(数学)异常
编程界非常严重的事情
1.除数为0,二进制维度上非常严重
2.输出输入流没有关闭(IO流);资源、程序没有关闭会造成蓝屏(比死机严重)
3.停电(以前台式机)
***当一个程序抛出异常,抛异常后面的代码不会运行,类似于return的作用,终止方法执行
public static void main(String[] args) {
//算数异常
int num1 = 10;
int num2 = 0;
System.out.println(num1/num2);//报错
int num3 = 10;
double num4 = 0.0;
System.out.println(num3/num4);//无穷大
BigDecimal bigDecimal1 = new BigDecimal("13");
BigDecimal bigDecimal2 = new BigDecimal("0.0");
System.out.println(bigDecimal1.divide(bigDecimal2));//报错
}
解决异常
- 关键字:try{}catch()
- 把有可能抛异常的代码放入try中
- catch()中写异常的类型
- 当try...catch出现异常后,程序继续进行
public static void main(String[] args) {
int num1 = 10;
int num2 = 0;
// 把有可能抛异常的代码放到try语句块里
try{
System.out.println(num1/num2);
//try中异常代码之后的代码不执行
System.out.println("我不重要。。。");
}catch (Exception e){
System.out.println("除数不能为0");
//打印异常信息
e.printStackTrace();
}
System.out.println("我很重要。。。");
}
异常的继承体系结构
Java万物皆对象,包括异常
最顶级的Throwable类
所有异常(Exception)和错误(Error)的父类
Error:正常情况下不太可能出现。绝大部分Error都会导致程序处于非正常情况下,很难恢复
- 错误一定是代码错了,是外力作用,一般不考虑。
- Error是Throwable的子类,它是在Java程序处理范围之外的
Exception:在Java语言中,将程序执行中发生的不正常的情况,称之为异常
1.编译期异常:写代码的时候抛异常,不是代码写错了。见的不多,见到了根据提示抛异常就ok了。
- 如果编译期异常不解决会一直报红
2.运行期异常:(常见)RuntimeException,运行时抛异常,平时没事
- 开发中大部分情况下,使用的都是运行期异常
自定义异常
Java中异常机制比较全面,但结合业务项目之后远远不够
例:在搜索框中输入火星文,要是在数据库中查找一遍没意义(谁会做火星文的数据库?),直接抛出异常
怎么自定义异常?
1.所有的异常必须是Throwable的子类(大材小用,开发中没必要用)
2.如果要定义一个编译期异常,需要继承Exception类
3.如果要定义一个运行期异常,需要继承RuntimeException类
面试题
写出五个运行期异常(恶心的是要写英文!)自己看!!!
编译期异常类
//继承异常父类,大材小用
public class MyException extends Exception{
public MyException(String message) {
super(message);
}
}
运行期异常类
public class MyRuntimeException extends RuntimeException{
public MyRuntimeException(String message) {
super(message);
}
}
怎么使用(抛)异常
- 关键字:throw 运行期异常
- 关键字:throws
在一个语句块中,如果抛出一个运行期异常throw抛一下就可以
public static void fun(int i,int j){
if (j == 0){
//运行期异常
throw new MyRuntimeException("除数不能为0");
}
System.out.println(i/j);
}
在一个语句块中,如果使用throw抛出一个编译器异常,必须在方法的声明处使用throws关键字标记异常类型(抛两边:throw抛对象,throws抛类型)
public static void fun(int i,int j) throws MyException{
if (j == 0){
//编译期异常
throw new MyException("除数不能为0");
}
System.out.println(i/j);
}
还有一种方式,就是直接try...catch
public static void fun(int i,int j){
if (j == 0){
//运行期异常
try {
throw new MyException("除数不能为0");
} catch (MyException e) {
e.printStackTrace();
}
}
System.out.println(i/j);
}
为什么要人为抛异常?
- 因为要配合全局异常处理机制解决问题
throw语句可以当做方法的返回值
在一个有返回值的方法中,如果有条件分支,一定要保证每种情况下都有返回值,哪怕是抛异常。
public static String show(String str){
if (Objects.isNull(str)){
return str.concat("hello");
}
//抛异常作为返回值
throw new RuntimeException("参数不能是空");
}
自定义异常类(ServiceException)
(此类我自己命名的)
开发中写自定义异常类的一般形式是我们自己定义的规则
public class ServiceException extends RuntimeException{
// 错误码
private Integer code;
// 异常信息
private String message;
public ServiceException() {
}
public ServiceException(Integer code, String message) {
this.code = code;
this.message = message;
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
@Override
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
异常链
- 一个异常被抛出去之后会继续被调用这个方法的方法捕获或抛出,异常会扩散。
- 只要说解决异常、处理异常、捕获异常,就是try... catch
- 看异常链从后往前看
class A{
public void a() {
throw new ServiceException(201,"业务异常...");
}
}
class B {
public void b() {
A aa = new A();
try {
aa.a();
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("b方法的语句");
}
}
class C {
public void c(){
B b = new B();
b.b();
System.out.println("c方法的语句..");
}
}
public class Ch05 {
public static void main(String[] args) {
C c = new C();
c.c();
System.out.println("Ch05的语句");
}
}
throws的特性
1、throws抛出的异常没有被真正的解决掉:
如果一个方法没有捕获(catch)一个编译期异常,该方法必须使用throws声明
(把异常抛出去,让调用此方法的方法处理异常,如果不处理就继续传导下一个,一般到主方法就不能抛了,要解决异常,在抛就给JVM了)
所以,throws不是真正的解决异常,只是把异常抛给了调用者,自己所在的方法不管了
public void info() throws MyException {
show();
}
// JVM
public static void main(String[] args) {
try {
new Ch06().info();
} catch (MyException e) {
throw new RuntimeException(e);
}
}
2、throws出现在什么地方?
方法的声明处,一个方法可以抛多个异常类型,用逗号隔开
public void show() throws MyException,RuntimeException,NullPointerException,IndexOutOfBoundsException {
}
面试题
throws和throw区别!!!
这大哥整理的好!!!
原文链接:https://blog.csdn.net/meism5/article/details/90414147
1、throw:
- 表示方法内抛出某种异常对象
- 如果异常对象是非 RuntimeException 则需要在方法申明时加上该异常的抛出 即需要加上 throws 语句 或者 在方法体内 try catch 处理该异常,否则编译报错
- 执行到 throw 语句则后面的语句块不再执行
2、throws:
- 方法的定义上使用 throws 表示这个方法可能抛出某种异常
- 需要由方法的调用者进行异常处理
————————————————
版权声明:本文为CSDN博主「ConstXiong」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/meism5/article/details/90414147
关键字:finally
finally用来创建在try代码块后面执行的代码块,try...catch...finally(常用)
finally作用:
无论是否发生异常。finally代码块的代码一定执行,finally代码块里一般用来释放资源
如果try里的异常没有catch住,则后面代码不执行,可能会停止不了代码流导致蓝屏,finally可以让后面的代码执行,
public static void main(String[] args) {
int num1 = 10;
int num2 = 2;
String str = null;
try {
System.out.println(num1 / num2);
System.out.println(str.length());
}finally{
System.out.println("finally...");
}
}
面试题
try...catch...finally执行顺序:
先走try,有异常走catch,内有异常不走catch
finally永远最后执行return永远在最后。
public class Question01 {
//不抛出异常:try---finally
public static int test1(){
int i = 10;
try {
i++;
System.out.println("try:" + i);
}catch (Exception e){
i--;
System.out.println("catch:" + i);
}finally {
i = 100;
System.out.println("finally:" + i);
}
return i;
}
//抛出异常:catch---finally
public static int test2(){
int i = 10;
try {
i++;
throw new Exception();
}catch (Exception e){
i--;
System.out.println("catch:" + i);
}finally {
i = 100;
System.out.println("finally:" + i);
}
return i;
}
// 在try中加return:try---finally---return(try中的)
public static int test3(){
int i = 10;
try {
i++;
System.out.println("try:" + i);
return i;
}catch (Exception e){
i--;
System.out.println("catch:" + i);
return i;
}finally {
i = 100;
System.out.println("finally:" + i);
}
}
// 在try和finally中都加return:try...finally...return(finally中的)
public static int test4(){
int i = 10;
try {
i++;
System.out.println("try:" + i);
return i;
}catch (Exception e){
i--;
System.out.println("catch:" + i);
return i;
}finally {
i = 100;
System.out.println("finally:" + i);
// return i;
}
}
public static void main(String[] args) {
// System.out.println(test1());
// System.out.println(test2());
// System.out.println(test3());
System.out.println(test4());
}
}
catch特性:
catch可以写多个,有顺序问题:
- 先写小的异常,后写大的异常
public static void main(String[] args) {
int num1 = 10;
int num2 = 0;
try {
System.out.println(num1 / num2);
// 开发角度来说,应该写指定的。
} catch (ArithmeticException e) {
// e.printStackTrace();
System.out.println("除数不能为0");
} catch (Exception e){
System.out.println("未知错误");
}
}
遗留问题
方法的重写:
- 重写的方法里不能抛出比被重写方法更大的异常类型
interface Inter01 {
void show() throws Exception;
}
public class Ch09 implements Inter01{
@Override
public void show() throws NullPointerException {
}
}
完事!