public class Test2 {
public static void main(String[] args) {
try{
Scanner scanner = new Scanner(System.in);
int a = scanner.nextInt();
int b = scanner.nextInt();
System.out.println(a / b);
} catch (Exception ex) {
System.out.println("对不起,程序出现异常!");
}
System.out.println("最后一句话");
}
}
把可能出现异常的代码放入try代码块中,然后将异常封装为对象,被catch后面的()中的那个异常对象接收,接收以后:执行catch后面的{}里面的代码,然后try-catch后面的代码,该怎么执行就怎么执行。
详细说一下:
(1)try中没有异常,catch中代码不执行。
(2)try中有异常,catch进行捕获:如果catch中异常类型和你出的异常类型匹配的话:走catch中的代码–》进行捕获, 如果catch中异常类型和你出的异常类型不匹配的话:不走catch中的代码–》没有捕获成功,程序相当于遇到异常了,中断了,后续代码不执行
注意:
(1)try中如果出现异常,然后用catch捕获成功的话,那么try中后续的代码是不会执行的。
(2)如果catch捕获异常成功,那么try-catch后面的代码该执行还是执行没有影响。
package P1.package2; import java.util.Scanner; public class Test2 { public static void main(String[] args) { try{ Scanner scanner = new Scanner(System.in); int a = scanner.nextInt(); int b = scanner.nextInt(); System.out.println(a / b); } catch (Exception ex) { // 处理方法1:什么都不写,什么都不做 // 处理方法2:输出自定义异常信息 System.out.println("对不起,程序出现异常!"); // 处理方法3:打印异常信息 // 3.1:调用tostring方法,打印异常的类名(全限定路径) System.out.println(ex.toString()); // 3.2: 显示异常描述信息对应的字符串,如果没有就显示null System.out.println(ex.getMessage()); // 3.3::显示异常的堆栈信息:将异常信息捕获以后,在控制台将异常的效果给我们展示出来,方便我们查看异常 ex.printStackTrace(); // 处理方法4:抛出异常 throw ex; } System.out.println("最后一句话"); } }
【1】在什么情况下,try-catch后面的代码不执行?
(1)throw抛出异常的情况
(2)catch中没有正常的进行异常捕获
(3)在try中遇到return
【2】怎么样才可以将 try-catch后面的代码 必须执行?
只要将必须执行的代码放入finally中,那么这个代码无论如何一定执行。
【3】return和finally执行顺序?
先执行finally最后执行return
【4】什么代码会放在finally中呢?
关闭数据库资源,关闭IO流资源,关闭socket资源。
【5】有一句话代码很厉害,它可以让finally中代码不执行!
[System.exit(0); //终止当前的虚拟机执行](file:///C:/Users/86159/Downloads/System.exit(0);/终止当前的虚拟机执行)
package P1.package2; import java.util.Scanner; public class Test2 { public static void main(String[] args) { try{ Scanner scanner = new Scanner(System.in); int a = scanner.nextInt(); int b = scanner.nextInt(); System.out.println(a / b); // 终止当前虚拟机执行 System.exit(0); return; } catch (Exception ex) { // 处理方法1:什么都不写,什么都不做 // 处理方法2:输出自定义异常信息 System.out.println("对不起,程序出现异常!"); // 处理方法3:打印异常信息 // 3.1:调用tostring方法,打印异常的类名(全限定路径) System.out.println(ex.toString()); // 3.2: 显示异常描述信息对应的字符串,如果没有就显示null System.out.println(ex.getMessage()); // 3.3::显示异常的堆栈信息:将异常信息捕获以后,在控制台将异常的效果给我们展示出来,方便我们查看异常 ex.printStackTrace(); // 处理方法4:抛出异常 throw ex; }finally { System.out.println("最后一句话"); } } } /* 12 4 3 Process finished with exit code 0 */ /* ww 对不起,程序出现异常! java.util.InputMismatchException null 最后一句话 java.util.InputMismatchException at java.util.Scanner.throwFor(Scanner.java:864) at java.util.Scanner.next(Scanner.java:1485) at java.util.Scanner.nextInt(Scanner.java:2117) at java.util.Scanner.nextInt(Scanner.java:2076) at P1.package2.Test2.main(Test2.java:9) Exception in thread "main" java.util.InputMismatchException at java.util.Scanner.throwFor(Scanner.java:864) at java.util.Scanner.next(Scanner.java:1485) at java.util.Scanner.nextInt(Scanner.java:2117) at java.util.Scanner.nextInt(Scanner.java:2076) at P1.package2.Test2.main(Test2.java:9) Process finished with exit code 1 */
【1】try中出现异常以后,将异常类型跟catch后面的类型依次比较,按照代码的顺序进行比对,执行第一个与异常类型匹配的catch语句
【2】一旦执行其中一条catch语句之后,后面的catch语句就会被忽略了!
【3】在安排catch语句的顺序的时候,一般会将特殊异常放在前面(并列),一般化的异常放在后面。
先写子类异常,再写父类异常。
【4】在JDK1.7以后,异常新处理方式:可以并列用|符号连接:
package P1.package2; import java.util.InputMismatchException; import java.util.Scanner; public class Test2 { public static void main(String[] args) { try { Scanner scanner = new Scanner(System.in); int a = scanner.nextInt(); int b = scanner.nextInt(); System.out.println(a / b); // 终止当前虚拟机执行 System.exit(0); return; } catch (ArithmeticException ex) { System.out.println("对不起,除数不可以为0"); } catch (InputMismatchException ex) { System.out.println("对不起,你录入的数据不是int类型的数据"); } catch (Exception ex) { System.out.println("对不起,你的程序出现异常"); } finally { System.out.println("最后一句话"); } } }
【1】层次结构:
注意:程序中语法错误,逻辑错误 都不属于上面的Error,Exception
一般的Exception默认是检查时异常
【2】检查异常:
处理方式1:try-catch嵌套try-catch
package P1.package2; public class Test3 { public static void main(String[] args) { //检查异常: try { try { Class.forName("Test3").newInstance(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } } catch (ClassNotFoundException e) { e.printStackTrace(); } } }
处理方式2:多重catch
package P1.package2; public class Test3 { public static void main(String[] args) { //检查异常: try { Class.forName("Test").newInstance(); } catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) { e.printStackTrace(); } } }
处理方式3:throws
package P1.package2; public class Test3 { public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException { //检查异常: Class.forName("Test").newInstance(); } }
(1)位置不同:
throw:方法内部
throws: 方法的签名处,方法的声明处
(2)内容不同:
throw+异常对象(检查异常,运行时异常)
throws+异常的类型(可以多个类型,用,拼接)
(3)作用不同:
throw:异常出现的源头,制造异常。 (出现问题就地解决)
throws:在方法的声明处,告诉方法的调用者,这个方法中可能会出现我声明的这些异常。然后调用者对这个异常进行处理:要么自己处理要么再继续向外抛出异常。(出现问题先不解决而是甩锅,甩给方法的调用着)
package P1.package2;
public class Test4 {
// 属性
private String name;
private int age;
private String sex;
// 方法
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getSex() {
return sex;
}
public void setSex(String sex) throws Exception {
if(sex == "男" || sex == "女") {
this.sex = sex;
}else {
// 制造运行时异常
//throw new RuntimeException("性别不对!");
// 制造检查异常
try {
throw new Exception();
} catch (Exception e) {
e.printStackTrace();
}
// 甩锅法
throw new Exception();
}
}
@Override
public String toString() {
return "Test4{" +
"name='" + name + '\'' +
", age=" + age +
", sex='" + sex + '\'' +
'}';
}
public Test4() {
}
public Test4(String name, int age, String sex) throws Exception {
this.name = name;
this.age = age;
/*
try {
this.setSex(sex);
} catch (Exception e) {
e.printStackTrace();
}
*/
this.setSex(sex);
}
//内部类
static class text5 {
public static void main(String[] args) throws Exception {
Test4 t1 = new Test4();
try {
t1.setSex("sdasd");
} catch (Exception e) {
e.printStackTrace();
}
Test4 t2 = new Test4("asd",10,"sdas");
}
}
}
【1】重载:
没啥关系
【2】重写:
子类 <= 父类
如果继承的是运行时异常,那么在使用的时候无需额外处理
如果继承的是检查异常,那么使用的时候需要try-catch捕获或者throws向上抛
package P1.package3;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.Scanner;
// Calendar训练
public class Test2 {
public static void main(String[] args) {
System.out.println("请输入你想要查看的日期:(提示:请按照例如2012-5-6的格式书写)");
Scanner scanner = new Scanner(System.in);
// 输入字符串类型的日期
String date = scanner.next();
// 将String类型转换成Calendar类型
// 分解法1:String -> Java.sql.Date 2: Java.sql.Date -> Calendar
java.sql.Date sqdate = java.sql.Date.valueOf(date);
Calendar cal = new GregorianCalendar();
cal.setTime(sqdate);
System.out.println("日"+"\t"+"一"+"\t"+"二"+"\t"+"三"+"\t"+"四"+"\t"+"五"+"\t"+"六");
// 获取当月中的最大日期
int maxDate = cal.getActualMaximum(Calendar.DATE);
// 获取当月中的这一天
int nowdate = cal.get(Calendar.DATE);
// 把当月的这一天设置成当月的第一天
cal.set(Calendar.DATE,1);
// 获取当月第一天在周几
int num = cal.get(Calendar.DAY_OF_WEEK);
int count = 0;
for (int i = 1; i < num; i++) {
System.out.print("\t");
count++;
}
for (int i = 1; i <= maxDate; i++) {
if(i == nowdate) {
System.out.print(i+ "*" + "\t");
}else {
System.out.print(i + "\t");
}
count++;
if(count == 7) {
System.out.println();
count = 0;
}
}
}
}