异常:代表程序出现的问题
异常的分类
RuntimeException:运行时异常(数组索引越界、空指针异常等,是代码运行时出现的异常)
其他异常:编译时异常(编译阶段要手动处理,不然报错)
区别在于:
异常的作用
①:作为查询bug的关键参考信息
②:作为方法内部的特殊返回值,以便通知调用者 底层的执行情况
以前数据超范围我们直接打印在控制台,现在通过抛出异常告诉调用者问题在哪,方便改bug,只需在超范围的地方加一句:throw new RuntimeException();
异常的处理方式
try{}catch{} 捕获处理异常
异常类名可以 ctrl+alt+t 快速生成;
在异常处创建异常对象,并且拿着该对象到catch括号中对比,若能被接受则表示被捕获,执行catch里面的代码;
执行完try catch后让程序继续往下执行,不会像上面处理异常时那样直接停止;
①:出现了异常才执行catch,没有问题则不执行catch里面的;
②:多个问题则一般写多个catch与异常对应,一旦遇到异常就直接进入对应catch,并且不再回头,后面的异常不会再显示了;
如果有父子关系则catch(父)要写在最下面;
如果不同异常对应的catch相同,则可以合并:
只有一个 | 另一个是光标...
③:没被捕获则相当于try catch白写,虚拟机采用默认方式自己处理异常
④:不会
异常中常见方法
try{
System.out.println(arr[10]);
}catch{
//返回此throwable的详细信息
String message = e.getMessage();
System.out.println(message);
//返回可抛出的简短描述
String str = e.toString();
System.out.println(str);
///把异常信息红色输出在控制台,且仅仅打印信息,不会停止程序运行
e.printStrackTrace();
}
抛出异常 throw 和 throws
停止继续运行
自定义异常
放在实例中了,要做到见名知意!
girls.java
package Nov15;
public class girls {
private String name;
private int age;
public girls() {
}
public girls(String name, int age) {
this.name = name;
this.age = age;
}
/**
* 获取
* @return name
*/
public String getName() {
return name;
}
/**
* 设置
* @param name
*/
//public void setName(String name) throws{
//运行异常 throws可以省略
//编译异常 throws不可以省略
public void setName(String name) {
int len = name.length();
if(len<3||len>10){
throw new NameFormatException(name+"格式有误,应为3~10");
}
this.name = name;
}
/**
* 获取
* @return age
*/
public int getAge() {
return age;
}
/**
* 设置
* @param age
*/
public void setAge(int age) {
if(age<18||age>40){
throw new AgeOutOfBoundsExcepiton(age+"超出范围");
}
this.age = age;
}
public String toString() {
return "girls{name = " + name + ", age = " + age + "}";
}
}
NameFormatException.java
package Nov15;
public class NameFormatException extends RuntimeException{
//alt+insert选择构造里面的前两个
public NameFormatException() {
}
public NameFormatException(String message) {
super(message);
}
}
AgeOutOfBoundsExcepiton.java
package Nov15;
public class AgeOutOfBoundsExcepiton extends RuntimeException{
public AgeOutOfBoundsExcepiton() {
}
public AgeOutOfBoundsExcepiton(String message) {
super(message);
}
}
test.java
package Nov15;
import java.util.Scanner;
public class test {
public static void main(String[] args) {
//创建键盘录入对象
Scanner sc = new Scanner(System.in);
//创建girl对象
girls g = new girls();
while (true) {
try {
//接收姓名
System.out.println("请输入姓名:");
String name = sc.nextLine();
g.setName(name);
//接收年龄
System.out.println("请输入年龄:");
String ageStr = sc.nextLine();
int age = Integer.parseInt(ageStr);
g.setAge(age);
//无异常即可跳出
break;
} catch(NumberFormatException e){
//当用户输入的字符串无法被正确解析为整数时,
//Integer.parseInt(ageStr) 将抛出 NumberFormatException 异常
e.printStackTrace();
}catch (NameFormatException e) {
e.printStackTrace();
//continue; 可省略
}catch (AgeOutOfBoundsExcepiton e){
e.printStackTrace();
//continue; 可省略
}
}
System.out.println(g);
}
}