异常概览
异常分为Exception和Error,Exception可以通过try-catch块处理,而Error是指程序发生错误,必须修改,如内存溢出
public class ErrorAndException {
public static void main(String[] args) {
int[] ar1 = new int[3];
try{
System.out.println(ar1[3]);
}catch(Exception e){
System.out.println("Exception handling:");
e.printStackTrace();
System.out.println("Exception handled.");
}
/*
Error示例:
int[] ar2 = new int[Integer.MAX_VALUE];
程序运行产生错误:
Exception in thread "main" java.lang.OutOfMemoryError: Requested array size exceeds VM limit
at demo07.demo02.main(demo02.java:21)
*/
}
}
throw字段
用throw在方法中抛出指定异常
格式:throw new XXException("…");
注意:
- throw必须写在方法内部
- throw抛出指定的异常对象,我们就必须处理这个异常对象
- throw抛出RuntimeException或者其子类对象异常,我们可以不处理,默认交给JVM处理
- throw抛出编译异常,我们必须处理这个异常,要么throws,要么try-catch
public class Demo02Throw {
public static void main(String[] args) {
int[] ar1 = null;
getElement(ar1, 0);
int[] ar2 = new int[0];
getElement(ar2, 0);
}
public static int getElement(int[] ar, int index) {
if (ar == null) {
throw new NullPointerException("数组引用为null"); //NullPointerException是一个运行期异常
}
if (index >= ar.length || index < 0) {
throw new IndexOutOfBoundsException("数组越界");
}
return ar[index];
}
}
Objects类方法
public class Demo03Objects {
public static void main(String[] args) {
method(null);
}
public static void method(Object obj){
Objects.requireNonNull(obj, "空对象");
}
}
throws字段
throws字段用于函数声明可能抛出的异常:
public class Demo04Throws {
public static void main(String[] args) throws IOException { //FileNotFoundException是IOException的子类,只需抛出父类异常
readFile("d:\\a/txt");
}
public static void readFile(String fileName) throws IOException { //readFile()将FileNotFoundException抛出
if(!fileName.equals("c:\\\\a.txt")){
throw new FileNotFoundException("文件路径不是c:\\a.txt"); //throw抛出编译异常FileNotFoundException,我们必须处理这个异常,要么throws,要么try-catch
}
if(!fileName.endsWith(".txt")){
throw new IOException("文件不是txt");
}
}
}
try-catch块
try-catch块用于捕获和处理异常:
public class Demo05TryCatch {
public static void main(String[] args) {
System.out.println("s:\\");
try {
//可能发生异常的代码
readFile("d:\\a.txt");
} catch (IOException e) {
//异常处理逻辑
System.out.println("异常处理:");
e.printStackTrace();
System.out.println(e.getMessage());
} finally {
/*
finally必须和try一起使用
finally一般用于资源释放(IO)
*/
//do something
}
System.out.println("后续代码");
}
public static void readFile(String fileName) throws IOException { //readFile()将FileNotFoundException抛出
if (!fileName.endsWith(".txt")) {
throw new IOException("文件不是txt");
}
if (!fileName.equals("c:\\a.txt")) {
throw new FileNotFoundException("文件路径不是c:\\a.txt"); //throw抛出编译异常FileNotFoundException,我们必须处理这个异常,要么throws,要么try-catch
}
}
}
多个异常的处理
public class Demo06MultiException {
public static void main(String[] args) {
method2();
}
//多个异常分别处理
public static void method1() {
List<Integer> list = new ArrayList<>();
try {
list.get(3);
} catch (Exception e) {
e.printStackTrace();
}
int[] ar = new int[3];
try {
System.out.println(ar[3]);
} catch (Exception e) {
e.printStackTrace();
}
}
//多个异常一次捕获,多次处理
public static void method2() {
List<Integer> list = new ArrayList<>();
int[] ar = new int[3];
try {
list.get(3);
System.out.println(ar[3]);
} catch (ArrayIndexOutOfBoundsException e) { //子类异常必须在父类异常之前被捕获
System.out.println("ArrayIndexOutOfBoundsException异常处理");
} catch (IndexOutOfBoundsException e) {
System.out.println("IndexOutOfBoundsException异常处理");
} finally {
System.out.println("finally子句");
}
}
//多个异常一次捕获,一次处理
public static void method3() {
try {
List<Integer> list = new ArrayList<>();
int[] ar = new int[3];
list.get(3);
System.out.println(ar[3]);
} catch (Exception e) { //子类异常必须在父类异常之前被捕获
System.out.println("Exception异常处理");
}
}
}
finally子句
public class Demo07Finally {
public static void main(String[] args) {
method();
}
public static int method(){
try{
return 1;
} catch(Exception e){
e.printStackTrace();
} finally { //只要finally中有return语句,永远返回finally中的结果
return 3;
}
}
}
子类和父类的异常抛出
- 如果父类方法抛出了多个异常,子类重写父类方法时,抛出和父类相同的异常或者不抛出异常
- 父类没有抛出异常,子类也不能抛出异常。这时子类产生异常,只能捕获,不能抛出
class SuperClass {
public void method1() throws NullPointerException {
}
public void method2() throws Exception {
}
public void method3() {
}
}
class SubClass extends SuperClass {
public void method1() throws NullPointerException {
}
// public void method1() throws Exception {} 报错
public void method2() throws NullPointerException { //可以抛出Exception的子类异常
}
public void method3() {
}
}
自定义异常
自定义异常一般是以Exception结尾,说明该类是一个异常
自定义异常,必须继承Exception或者RuntimeException:
1.继承Exception,那么自定义的异常类是一个编译期异常,一经抛出必须处理
2.继承RuntimeException,那么自定义的异常类是一个运行期异常,可以不处理
自定义异常的格式通常如下:
class CustomException extends Exception {
/*
添加一个空参数的构造方法
添加一个带异常信息的构造方法
*/
public CustomException(){
super();
}
public CustomException(String message){
super(message);
}
}
模拟用户注册练习
/*
1.用集合保存已经注册用户名
2.使用Scanner获取用户输入的注册用户名
3.使用方法对用户名进行注册
*/
public class Demo10ExceptionExercise {
private static Set<String> registeredNames = new HashSet<>();
public static void main(String[] args) throws RegisterException {
Scanner sc = new Scanner(System.in);
System.out.println("输入注册的用户名:");
String userName = sc.next();
register(userName);
}
public static void register(String userName) throws RegisterException {
if(registeredNames.contains(userName))
throw new RegisterException();
registeredNames.add(userName);
}
}
class RegisterException extends Exception {
public RegisterException() {
super();
}
public RegisterException(String message) {
super(message);
}
}
503

被折叠的 条评论
为什么被折叠?



