JavaSE核心API--异常类
java.lang.Exception
1)理论讲解:自动关闭
JDK1.7之后推出了一个新的特性:自动关闭
使用该特性,对于IO操作后的关闭变得比较简单了。
代码演示:
try(
/*
* JDK1.7之后提供了一个接口:AutoCloseable
* 实现了该接口的类可以在此定义,最终会在finally中被关闭(编译器会在编译后改变代码)
*/
FileOutputStream fos
= new FileOutputStream("fos.dat");
){
fos.write(1);
} catch (Exception e) {
System.out.println("出错了!");
}
2)理论讲解:异常常用方法
代码演示:
System.out.println("程序开始了!");
try {
String str="a";
System.out.println(Integer.parseInt(str));//该行代码出错--at exception.ExceptionApiDemo.main(ExceptionApiDemo.java:11)
System.out.println("helloWorld");
} catch (Exception e) {
System.out.println("出错啦!");
//调用printStackTrace()方法输出错误堆栈信息,有助于我们解决错误,去找到at我们写的那个类
// e.printStackTrace();//这个是最常用的
String message=e.getMessage();
System.out.println(message);//结果输出For input string: "a"---告知用户因为你输入的是字符串a,不能转成整型数字
}
System.out.println("程序结束了!");
3)理论讲解:finally块
finally块
finally是异常处理机制的最后一块。它可以直接跟在try语句块之后,或者最后一个catch块之后。
finally能确保只要程序执行到try语句块中,无论try语句块中的代码是否抛出异常,finally块中的代码必定执行。
通常会将无关乎程序出错都要执行的代码放在这里,比如资源的释放操作:IO里的流关闭。
代码演示:
System.out.println("程序开始了");
try {
String str = "";
System.out.println(str.length());
return;
} catch (Exception e) {
System.out.println("出错了!");
} finally {
System.out.println("finally中的代码执行了!");
}
System.out.println("程序结束了");
4)理论讲解:finally在IO中的使用
代码演示:
FileOutputStream fos = null;
try {
fos = new FileOutputStream("fos.dat");
fos.write(1);
} catch (Exception e) {
System.out.println("出错了");
} finally {
try {
if(fos!=null) {
fos.close();
}
} catch (IOException e) {
}
}
5)理论讲解:finally常见笔试题
finally常见笔试题
1:下面的代码
2:请分别说明:final,finally,finalize?
finalize方法是Object中定义的方法,当一个对象即将被GC释放时,GC会调用该方法。调用后即被GC释放。
通常我们不会重写这个方法,若需要在一个对象被释放前做某些操作时可以重写该方法。
但是注意!该方法不应当包含耗时的操作。否则会影响GC的回收工作。
代码演示:
public static void main(String[] args) {
System.out.println(
test("0")+","+test(null)+","+test("")
);
//3,3,3
}
@SuppressWarnings("finally")
public static int test(String str) {
try {
System.out.println("test:"+str);
return str.charAt(0)-'0';
} catch (NullPointerException e) {
System.out.println("空指针");
return 1;
} catch (Exception e){
System.out.println("其他异常");
return 2;
} finally {
System.out.println("test:"+str+",finally执行了!");
return 3;
}
}
6)理论讲解:自定义异常
自定义异常
通常自定义异常是用来说明业务逻辑错误。
年龄不合法异常
当年龄超过取值范围时,会抛出该异常。
代码演示:
public class IllegalAgeException extends Exception{//年龄不合法异常
/**声明序列化版本号*/
private static final long serialVersionUID = 1L;
/**从父类中添加构造方法*/
public IllegalAgeException() {
super();
// TODO Auto-generated constructor stub
}
public IllegalAgeException(String arg0, Throwable arg1, boolean arg2, boolean arg3) {
super(arg0, arg1, arg2, arg3);
// TODO Auto-generated constructor stub
}
public IllegalAgeException(String arg0, Throwable arg1) {
super(arg0, arg1);
// TODO Auto-generated constructor stub
}
public IllegalAgeException(String arg0) {
super(arg0);
// TODO Auto-generated constructor stub
}
public IllegalAgeException(Throwable arg0) {
super(arg0);
// TODO Auto-generated constructor stub
}
}
7)理论讲解:使用当前类测试异常的抛出
代码演示:
public class Person {
private int age;
public int getAge() {
return age;
}
/**
* 通常一个方法中通过throw抛出什么异常,就要在方法声明的同时使用throws声明该异常的抛出
* 当一个方法声明了异常抛出后,那么当调用该方法时编译器会要求调用的代码片段必须处理该异常
* 注:只有方法中抛出RuntimeException及其子类型异常时,可以不用在方法声明时使用throws声明该类异常的抛出
*
* @param age
* @throws ExceptionDemo
*/
public void setAge(int age) throws IllegalAgeException {// throws用于告知调用者该方法有异常需要处理
if (age < 0 || age > 100) {
throw new IllegalAgeException("年龄不合法!");// throw用于抛异常
}
this.age = age;
}
}
8)理论讲解:异常的抛出
异常的抛出
throw关键字用于将一个异常抛出------通常遇到以下情况我们会主动在一个方法中抛出异常:
1.程序运行时出现了一个异常,但是该异常不应当在当前方法中被解决时,可以给调用者处理
2.程序运行时出现了不符合业务逻辑的情况时,可以主动实例化一个异常抛出给调用者告知其这样的调用不合理----java没有提供,要自定义异常(见名知意)
代码演示:
public static void main(String[] args) {//不能在main方法用throws
Person p=new Person();
try {
/*
* 当我们调用一个含有throws声明异常抛出的方法时,编译器要求我们必须处理该异常,否则编译不通过
* 处理异常的手段有两种:
* 1.使用try-catch捕获该方法throws声明抛出的异常-----应该归我管则处理
* 2.在当前方法上继续使用throws声明该异常的抛出-------不归我管则继续往外抛
*/
p.setAge(1000);//调用抛异常的方法的同时必须要用try-catch处理该异常
} catch (IllegalAgeException e) {
e.printStackTrace();
// System.out.println("出错啦!");
}
System.out.println(p.getAge());
}
9)理论讲解:重写含有throws声明异常抛出的方法时对throws的重写准则
代码演示:
public class ThrowsDemo {
public void dosome() throws IOException,AWTException {}
}
class Boo extends ThrowsDemo{
// @Override
// public void dosome() throws IOException,AWTException {}
// /**
// * 可以仅抛出超类方法的部分异常
// */
// @Override
// public void dosome() throws IOException {}
// /**
// * 可以不再抛出任何异常
// */
// @Override
// public void dosome(){}
// /**
// * 可以抛出超类方法的部分异常中的子类型异常
// */
// @Override
// public void dosome() throws FileNotFoundException {}//FileNotFoundException虽然超类方法中没有,但它是IOException的子类
// /**
// * 不可以抛出额外异常
// * 即:超类中没有的异常,并且也没有继承关系的异常
// */
// public void dosome() throws SQLException{}
/**
* 方法的重写:----重新写,覆盖
* 1)发生在父子类中,方法签名一样(方法名称相同,参数列表相同),方法体不同
* 2)重写方法被调用时,看对象的类型
* 3)遵循“两同两小一大”原则:------了解
* 3.1)两同:
* 3.1.1)方法名称相同
* 3.1.2)参数列表相同
* 3.2)两小:
* 3.2.1)派生类方法的返回值类型小于或等于超类方法的
* 1)void时,必须相等
* 2)基本类型时,必须相等
* 3)引用类型时,小于或等于
* 3.2.2)派生类方法抛出的异常小于或等于超类方法的-----异常之后讲
* 3.3)一大:
* 3.3.1)派生类方法的访问权限大于或等于超类方法的-----明天上午讲
*/
// /**
// * 不允许抛出超类方法的部分异常中的父类型异常-----派生类方法抛出的异常小于或等于超类方法的
// */
// public void dosome() throws Exception{}//Exception虽然超类方法中没有,但它是IOException的父类
}
10)理论讲解:java异常处理机制中的try-catch
java异常处理机制中的try-catch
try{
可能出现异常的代码片段
}catch(XXXException e){
当出现了XXXException后的处理代码
}
代码演示:
System.out.println("程序开始了");
try {
// String str = null;
// String str = "";
String str = "a";
/*
* 当JVM执行过程中出现某个异常时会实例化对应的异常实例,并将程序执行过程设置进去。
* 这时该异常实例可以完整说明当前情况。
* 实例化完毕后,JVM会将该异常抛出
*/
System.out.println(str.length());
System.out.println(str.charAt(0));
System.out.println(Integer.parseInt(str));
// try语句块中出错代码以下的内容都不会执行
System.out.println("!!!!!");
} catch (NullPointerException e) {
System.out.println("出现了空指针!");
} catch (StringIndexOutOfBoundsException e) {
System.out.println("字符串下标越界了!");
/*
* 通常会在最后一个catch中捕获Exception,防止 因为一个未捕获的异常导致程序中断
*/
} catch (Exception e) {
System.out.println("反正就是出了个错!");
}
System.out.println("程序结束了");