第五章 异常Exception
第一节 异常(Exception)
我们先给出一个例子,看看异常有什么用?
例:1.1-本章源码
public class Test {
public static void main(String[] args) {
int userInput=0;
int I = 6 / userInput;
System.out.println("马克-to-win:优雅结束");
}
}
输出结果:
Exception in thread "main" java.lang.ArithmeticException: / by zero
at Test.main(Test.java:4)
例:1.1.2-本章源码
public class Test {
public static void main(String[] args) {
try
{
int userInput=0;
int I = 6 / userInput;
System.out.println("马克-to-win:inside try");
}
/*系统把错误信息放在Exception的对象e中,马克-to-win*/
catch(Exception e)
{
System.out.println(e);
}
System.out.println("马克-to-win:优雅结束");
}
}
输出结果:
java.lang.ArithmeticException: / by zero
马克-to-win:优雅结束
异常的意义:马克-to-win: (视频下载) (全部书籍)通过上面的例子,我们看出通过引入异常这种技术,即使出现不测(用户把0赋给除数),也可以让程序不崩溃,还能继续优雅的运行。那,这种技术有用,值得学。马克-to-win:当你批量下载文件时,如出现什么错误,你是不是希望下载器能告诉你出现了什么问题,比如硬盘不足等等,在你提供了足够的硬盘空间以后,下载继续自动进行。而不是说空间一不足,立刻下载器就崩溃呀!这就是异常技术。
异常这种技术框架是怎么工作的?【新手可忽略不影响继续学习】 (视频下载) (全部书籍)马克-to-win:注意是运行程序时,而不是编译时,当一个非正常情况出现,比如除0,就叫异常情况。马克-to-win:为了能优雅的处理异常情况(在出现异常情况后,程序不崩溃,还能继续优雅的运行), Sun公司设计了异常技术框架,马克-to-win:你把可能出现问题的语句放在try块儿中,真出了问题的话,系统会把问题的信息存放在一个异常类的对象中传入到catch块中,在catch块儿中,你可以专门根据错误信息作处理。这样业务代码放在try块儿中,错误处理代码放在catch中,好处是易读,条理清楚。马克-to-win:没有try catch这种异常技术前,业务代码和排错代码是搅和在一起的!
例:1.1.3-本章源码
public class Test {
public static void main(String[] args) {
try
{
int userInput=0;
int I = 6 / userInput;
}
catch(ArithmeticException e)
{
System.out.println(e);
}
System.out.println("马克-to-win:优雅结束");
}
}
输出结果:
java.lang.ArithmeticException: / by zero
马克-to-win:优雅结束
顺便提一句, (视频下载) (全部书籍)和Exception相对应的,还有Error,Error(错误)表示系统级的错误和程序不必处理的异常,是JRE(java运行环境)的内部错误或者硬件问题,比如,另外某一处地方的bug引起的内存溢出,内存资源不足等,OutOfMemoryError,对这类错误,程序基本无能为力,比如下例中,catch不被执行(其实虚拟机是有能力执行的,否则finally为什么被执行?但就是这原则,意味着,程序员们不要试图在catch中做什么,你做了, 我也不执行,因为是Error,而不是Exception)只能退出。
例:
public class Test {
/* maxMemory将返回java虚拟机所能返回的最大可用内存。0.92可以, 0.93就报错 */
int size_Make_to_win = (int) (Runtime.getRuntime().maxMemory() * 0.93);
public void allo() {
byte[] data1 = new byte[size_Make_to_win];
}
public static void main(String[] args) {
Test t = new Test();
try{
t.allo();
}
catch(Exception e)
{
System.out.println(e+"qqq");
}
finally
{
System.out.println("in finally");
}
}
}
输出结果:
in finally
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at Test.allo(Test.java:5)
at Test.main(Test.java:10)
马克-to-win:什么叫多重捕获MultiCatch?一段代码可能引起多个异常,这时可以定义两个或更多的catch子句来处理这种情况,每个子句捕获一种类型的异常。马克-to-win:异常被引发时,每一个catch块儿被依次检查,第一个匹配异常类型的catch块儿被执行。马克-to-win:当一个catch块儿执行以后,其他的catch块儿被跳过,继续try/catch块以后的代码。像switch一样。
例:1.2.2-本章源码
public class Test {
public static void main(String[] args) {
int arg1;
int result;
// String s="abc";
String s="12";
try {
arg1 = Integer.parseInt(s);
result = arg1 /0;//马克-to-win:这里会再次抛出异常,使程序崩溃
System.out.println("try中完成finish");
}
catch (NumberFormatException e) {
System.out.println("输入参数必须为整数!");
}
System.out.println("马克-to-win:优雅结束");
}
}
输出结果:
Exception in thread "main" java.lang.ArithmeticException: / by zero
at Test.main(Test.java:9)
观察例1.2.2可知:马克-to-win:由于我们少捕获一个除0异常,程序崩溃, 很可怕。程序进一步修改如下:
例:1.2.3-本章源码public class Test {
public static void main(String[] args) {
int arg1;
int result;
// String s="abc";
String s="12";
try {
arg1 = Integer.parseInt(s);
result = arg1 /0;
System.out.println("try中完成finish");
}
catch (NumberFormatException e) {
System.out.println("输入参数必须为整数!");
} catch (ArithmeticException e) {
System.out.println("除数不能为0");
}
System.out.println("马克-to-win:优雅结束");
}
}
结果如下:
除数不能为0
马克-to-win:优雅结束
马 克-to-win:程序又一次在出现问题的情况下,优雅结束了。上例中蓝色部分是多重捕获catch。马克-to-win:观察上面三个例子,结论就是即 使你已经捕获了很多异常,但是假如你还是少捕获了什么异常,赶上那个异常发作,你程序还是会崩溃的。马克-to-win:但是有读者说,我的经验就是不足,老是少捕获什么异常,那怎么办呀?我们可以求助于下一节的技术,Exception类捕获所有的异常。
马克-to-win: (视频下载) (全部书籍)程序又一次在出现问题的情况下,优雅结束了。上例中蓝色部分是多重捕获catch。马克-to-win:观察上面三个例子,结论就是即使你已经捕获了很多异常,但是假如你还是少捕获了什么异常,赶上那个异常发作,你程序还是会崩溃的。马克-to-win:但是有读者说,我的经验就是不足,老是少捕获什么异常,那怎么办呀?我们可以求助于下一节的技术,Exception类捕获所有的异常。
3.用Exception类捕获所有异常 (视频下载) (全部书籍)马克-to-win: (视频下载) (全部书籍)一个重要的技巧就是:catch多重异常时,子异常类必须在它们任何父类之前。马克-to-win:因为运用父类的catch语句将捕获该类型及其所有子类类型的异常。马克-to-win:这样,如果子类在父类后面,子类将永远不会到达。马克-to-win:你想写也不行,系统会报编译错误。
马克-to-win:我们先说5/0的原理,当程序运行到5/0的时候,java系统JVM会在后台new出一个除0异常实例,之后把这个实例传入catch块儿供开发者使用。马克-to-win:而这里throw new Exception();是开发者自己主动new出一个异常实例,之后把这个实例传入catch块儿供开发者自己使用。马克-to-win:对于catch来讲,不管谁抛的,处理起来都一样。
(新手必须忽略)意义是什么?见后面的sun的例子(1.5.4_a):if(url==null) throw new sqlException见例:1.5.4,这样就可以做到,有经验的人(这里是sun公司),预感到大家都易犯url==null这样的毛病(你开始不知道),于是他就throw new sqlException,(但是在sun公司写那段代码时,他又不能处理,因为逻辑上,就应该是你后来者的任务或说义务,举一个例子,爷爷规定遗产只能干教育,具体是生物还是物理或是数学他并不管,这里就是你必须管,但怎么管,怎么catch,你来做定夺,前人无法替你做决定)逼着你这个新手,必须catch这样的毛病,否则你的程序会崩溃。提醒你了,你不处理都不行。
例:1.5.1-本章源码
public class Test {
public static void main(String[] args) {
int mark_to_win = 0;
int c;
if (mark_to_win == 0) throw new ArithmeticException("divide by 0");
else c=8/mark_to_win;
System.out.println("马克-to-win:优雅结束");
}
}
输出结果:
Exception in thread "main" java.lang.ArithmeticException: divide by 0
at Test.main(Test.java:5)
例:1.5.2-本章源码
public class Test {输出结果:
Exception in thread "main" java.lang.ArithmeticException: / by zero
at Test.main(Test.java:5)
马
克-to-win:通过观察,我们发现上面两个例子最后报的异常的地方是一样的!异常的效果也是等价的!马克-to-win:如上面我们的讲的,只不过一
个是JVM系统抛出的,一个是我们自己主动抛出的。马克-to-win:所以为了不让系统崩溃,我们需要像原来一样捕获一下异常就可以了。
例:1.5.3-本章源码
public class Test {
public static void main(String[] args) {
int mark_to_win = 0;
int c;
try{
if (mark_to_win == 0) throw new ArithmeticException("divide by 0");
else c=8/mark_to_win;
}catch(ArithmeticException a)
{
System.out.println(a);
}
System.out.println("马克-to-win:优雅结束");
}
}
输出结果:
java.lang.ArithmeticException: divide by 0
马克-to-win:优雅结束
例:1.5.4_a:
private static Connection getConnection(
String url, java.util.Properties info, Class<?> caller) throws SQLException {
/*
* When callerCl is null, we should check the application's
* (which is invoking this class indirectly)
* classloader, so that the JDBC driver class outside rt.jar
* can be loaded from here.
*/
ClassLoader callerCL = caller != null ? caller.getClassLoader() : null;
synchronized(DriverManager.class) {
// synchronize loading of the correct classloader.
if (callerCL == null) {
callerCL = Thread.currentThread().getContextClassLoader();
}
}
if(url == null) {
throw new SQLException("The url cannot be null", "08001");
}
例:1.5.4(参考视频讲课用,新手必须忽略)
import java.sql.SQLException;马克-to-win:为什么我大胆的把Checked Exception翻译成受检的异常?因为这类异常,编译器检查发现到它后会强令你catch它或throws它(我们之后讲),马克-to-win:而相对于本节前面我们提到的各种比如ArithmeticException,都是unchecked exception(不受检)的异常,unchecked异常都是RuntimeException或者它的子类。马克-to-win:换句话:编译器检查发现到它以后,什么都不管,也什么都不做,直接放行。见下面的例子:
例:1.6.1-本章源码
public class Test {
void m1_mark_to_win() {
throw new RuntimeException("divide by 0");
}
public static void main(String[] args) {
Test t=new Test();
t.m1_mark_to_win();
}
}
输出结果:
Exception in thread "main" java.lang.RuntimeException: divide by 0
at Test.m1_mark_to_win(Test.java:3)
at Test.main(Test.java:7)
例:1.6.2(编译报错,不能运行)-本章源码
import java.io.FileNotFoundException;
public class Test {
void m1_mark_to_win() {
throw new FileNotFoundException();
}
public static void main(String[] args) {
Test t=new Test();
t.m1_mark_to_win();
}
}
在throw new FileNotFoundException();外面,马克-to-win:必须包上一个try catch块儿,程序才能通过编译。
例:1.6.3-本章源码
import java.io.FileNotFoundException;
public class Test {
void m1_mark_to_win() {
try {
throw new FileNotFoundException();
} catch (FileNotFoundException e) {
System.out.println(" in catch");
e.printStackTrace();
}
}
public static void main(String[] args) {
Test t=new Test();
t.m1_mark_to_win();
System.out.println("马克-to-win:优雅结束");
}
}
输出结果:
in catch
马克-to-win:checked和unchecked异常区别: (视频下载) (全部书籍)结论就是:1)RuntimeException和他的子类都是unchecked异常。其他的都是checked异常。马克-to-win:2)在编译阶段,编译器会检查每一个方法,看是否方法里面抛出了checked异常。假设抛出了checked异常,那个方法里必须加catch,或者加throws语句(下一节讲解),否则的话编译器会报错。马克-to-win:unchecked异常就没这规矩。
马克-to-win:拿上一节,1.6.2为例,当时有问题,我们用catch解决了,当然我们也可以用throws技术搞定它。
例:1.7.1(本例编译有错误)-本章源码
import java.io.FileNotFoundException;
public class Test {
void m1_mark_to_win() {
throw new FileNotFoundException();
}
}
马 克-to-win:上例编译有错误,因为FileNotFoundException是checked异常, 所以我们必须加catch马上处理或用throws留待将来处理。catch我们这里就不说了。马克-to-win:上节有论述。我们这里用throws 来处理。
例:1.7.2(可通过编译)-本章源码
import java.io.FileNotFoundException;
public class Test {
void m1_mark_to_win() throws FileNotFoundException {
throw new FileNotFoundException();
}
}
像下面的子类也可以
例:1.7.2_2(可通过编译)-本章源码
import java.io.*;这里FileNotFoundException是IOException 的子类。
java.lang.Object
java.lang.Throwable
java.lang.Exception
java.io.IOException
java.io.FileNotFoundException
马 克-to-win:注意:例:1.7.2,编译就没问题了,但是throws FileNotFoundException,只是标记了一下问题,并没有真正处理,运行到throw new FileNotFoundException();时,程序还是会崩溃。马克-to-win:不信,下面我们就加一个主调方法测试一下。
例:1.7.3(本例编译有问题)-本章源码
import java.io.FileNotFoundException;
public class Test {
void m1_mark_to_win() throws FileNotFoundException {
throw new FileNotFoundException();
}
public static void main(String[] args) {
Test t=new Test();
t.m1_mark_to_win();//这句会报红线
System.out.println("马克-to-win:优雅结束");
}
}
马 克-to-win:例:1.7.3的主调方法t.m1_mark_to_win();又有问题了,因为被调方法m1_mark_to_win()里面有一 个没有处理的throw异常,所以主调方法还是编译不过。马克-to-win:我们必须或者catch或者throws处理,catch上一节讲了,现在 我们不讲。这里我们用throws,等于还是没有处理,程序运行到这还是会崩溃。马克-to-win:下面我们看一下运行结果。
例:1.7.4-本章源码
import java.io.FileNotFoundException;
public class Test {
void m1_mark_to_win() throws FileNotFoundException {
throw new FileNotFoundException();
}
public static void main(String[] args) throws FileNotFoundException {
Test t=new Test();
t.m1_mark_to_win();
System.out.println("马克-to-win:优雅结束");
}
}
输出结果:
Exception in thread "main" java.io.FileNotFoundException
at Test.m1_mark_to_win(Test.java:4)
at Test.main(Test.java:8)
马克-to-win:结果分析:当程序运行t.m1_mark_to_win();程序崩溃了,连System.out.println("马克-to-win:优雅结束");都没有执行。要想不崩溃, 只能加try catch。
例:1.7.5-本章源码
import java.io.FileNotFoundException;
public class Test {
void m1_mark_to_win() throws FileNotFoundException {
throw new FileNotFoundException();
}
public static void main(String[] args) {
Test t=new Test();
try {
t.m1_mark_to_win();
} catch (FileNotFoundException e) {
System.out.println(e);
}
输出结果:
java.io.FileNotFoundException
马克-to-win:优雅结束
马克-to-win:下面的例子1.7.6,多了一层调用,道理是一样的, 仅供参考。一直用throws做缓兵之计,没有解决问题,所以程序最后还是崩溃了!catch才能真正解决问题。
例:1.7.6-本章源码
import java.io.FileNotFoundException;输出结果:
Exception in thread "main" java.io.FileNotFoundException8.throws子句在继承当中overrride时的规则 (视频下载) (全部书籍)
马克-to-win:当子类方法override父类方法时,throws子句不能引进新的checked异常。换句话说:子类override方法的throws子句checked异常不能比父类多。马克-to-win:上面一条是死语法规定,这种规定,实际上都是源于checked异常这种最初的设计。例:1.8.1-本章源码
import java.io.IOException;
class Animal{
void call() throws IOException
{
System.out.println("Animal");
}
}
class Dog extends Animal{
void call() throws IOException
{
System.out.println("Dog");
}
}
public class Test {
public static void main(String args[]) throws IOException {
Dog d = new Dog();
d.call();
}
}
输出结果:
Dog9.创建自定义异常 Create Custom Exception (视频下载) (全部书籍)
马克-to-win:我们可以创建自己的异常:checked或unchecked异常都可以, 规则如前面我们所介绍,反正如果是checked异常,则必须或者throws,或者catch。到底哪个好,各路架构师大神的意见是50对50。见我本章后面的附录。sun公司开始说,checked异常可以使你的系统异常语义表达很清楚。但很多人经过一段时间的实践后,马上表示了异议。checked异常是java独有的,但连Thinking in java的作者都表示,checked异常作为一种java特有的实验行为,不是很成功。我个人的意见是:为了达到解耦的目的,最好继承unchecked异常。否则你各种业务方法都得throws。将来业务方法一旦改变,还得考虑处理这些throws。(新手可忽略)比如你的业务方法a里如果新加了一句throw受检异常,而且你还没有catch,则调用你这个a方法的客户程序将必须或者catch或者throws,反正必须做出相应调整。如果当初你的a方法里只是抛出一个非受检异常,客户程序就不用做任何调整了。例1.9.1-本章源码
public class Test {
public static void main(String args[]) throws RelationshipExceptionMark_to_win {
int talkTimesPerDay = 2;
if (talkTimesPerDay < 3) {
RelationshipExceptionMark_to_win e = new RelationshipExceptionMark_to_win();
e.setMsg("每天说话小于3 次,抛出关系异常的异常,分手");
System.out.println("马克-to-win:here");
throw e;
}
System.out.println("马克-to-win:优雅结束");
}
}
class RelationshipExceptionMark_to_win extends Exception {
String msg;
String getMsg() {
return msg;
}
void setMsg(String msg) {
this.msg = msg;
}
}
输出结果:
马克-to-win:here
Exception in thread "main" RelationshipExceptionMark_to_win
at Test.main(Test.java:5)
public class Test {
public static void main(String args[]) {
int talkTimesPerDay = 2;
if (talkTimesPerDay < 3) {
RelationshipExceptionMark_to_win e = new RelationshipExceptionMark_to_win();
e.setMsg("每天说话小于3 次,抛出关系异常的异常,分手");
throw e;
}
System.out.println("马克-to-win:优雅结束");
}
}
class RelationshipExceptionMark_to_win extends RuntimeException {
String msg;
String getMsg() {
return msg;
}
void setMsg(String msg) {
this.msg = msg;
}
}
输出结果:
Exception in thread "main" RelationshipExceptionMark_to_win
at Test.main(Test.java:5)
例1.9.3-本章源码
public class Test {输出结果:
每天说话小于3 次,抛出关系异常的异常,分手
马克-to-win:优雅结束
马克-to-win:finally块儿是怎么工作的?有什么意义?finally关键字创建一个代码块。没有try,finally块儿不能单独存在。该代码块在一个try/catch块完成之后另一个try/catch出现之前执行。马克-to-win:finally一定会执行,即使 1)异常没有发生 2)根本没有写catch块儿 3)没有与该异常相匹配的catch子句。4)try代码块中包含有break、continue、return或者throw语句(或直接崩溃或发生OutOfMemoryError)。
为什么抛出异常或发生错误,finally块儿还是能运行呢?想象一下程序执行的过程就明白了。jvm一句一句的向下执行,当它发现数组过界时,它就先执行finally块儿,然后再执行打印报错现在正在发生数组过界。注意现在是你的程序出现问题,jvm一点问题都没有,所以它还能正常打印报错。(见下面的例子)马克-to-win: (视频下载) (全部书籍)finally有什么意义呢,在现实中?比如你开了一个流处理文件,可能没开成功,或开成功了,但后面的操作失败了,但不管你怎么样,你必须在一个地儿把它关闭,那就是finally块儿。
例: 1.10.1(try catch全齐,正常情况)-本章源码
public class Test {
public static void main(String[] args) {
try
{
int userInput=0;
int I = 6 / userInput;
}
catch(Exception e)
{
System.out.println(e);
}
finally
{
System.out.println("in finally");
}
System.out.println("马克-to-win:优雅结束");
}
}
输出结果:
java.lang.ArithmeticException: / by zero
in finally
马克-to-win:优雅结束
例: 1.10.2(异常没有发生)-本章源码
public class Test {
public static void main(String[] args) {
try
{
int userInput=2;
int I = 6 / userInput;
}
catch(Exception e)
{
System.out.println(e);
}
finally
public class Test {
public static void main(String[] args) {
try
{
int userInput=2;
int I = 6 / userInput;
}
finally
{
System.out.println("in finally");
}
System.out.println("马克-to-win:优雅结束");
}
}
输出结果:
in finally
马克-to-win:优雅结束
public class Test {
public static void main(String[] args) {
try {
String str = null;
str = str.toUpperCase();//本应捕获空指针异常
} catch (ArithmeticException e) {//这里却想捕获数学异常, 完全捕不到
System.out.println(e);
}
finally {//finally一定会被执行
System.out.println("here is in final block.");
}
System.out.println("马克-to-win:优雅结束");
}
}
输出结果:
public class Test {
static void subRMark_to_win() {
try {
System.out.println("子程序");
int a=1/0;
}
finally {
System.out.println("子程序的finally");
}
}
public static void main(String args[]) {
try {
subRMark_to_win();
} catch (Exception e) {
System.out.println("主程序的catch");
}
System.out.println("马克-to-win:优雅结束");
}
}
输出结果:
子程序
子程序的finally
主程序的catch
马克-to-win:优雅结束
public class Test {
static void subRMark_to_win() {
try {
System.out.println("子程序");
throw new RuntimeException();
}
finally {
System.out.println("子程序的finally");
}
}
public static void main(String args[]) {
try {
subRMark_to_win();
} catch (Exception e) {
System.out.println("主程序的catch");
}
System.out.println("马克-to-win:优雅结束");
}
}
例: 1.10.6_a(try代码中有OutOfMemoryError,依旧执行finally)
import java.util.Vector;
class Mark_to_win {
long data;
}
public class Test {
static Vector v = new Vector(10);
static void subRMark_to_win() {
try {
System.out.println("子程序");
int size_Make_to_win = (int) (Runtime.getRuntime().maxMemory() * 0.8);
for (int i = 1; i < size_Make_to_win; i++) {
Mark_to_win m = new Mark_to_win();
v.add(m);
m = null;
}
}
finally {
System.out.println("子程序的finally");
}
}
public static void main(String args[]) {
try {
subRMark_to_win();
} catch (Exception e) {
System.out.println("主程序的catch");
}
System.out.println("马克-to-win:优雅结束");
}
}
输出:
子程序
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOf(Unknown Source)
at java.util.Arrays.copyOf(Unknown Source)
at java.util.Vector.grow(Unknown Source)
at java.util.Vector.ensureCapacityHelper(Unknown Source)
at java.util.Vector.add(Unknown Source)
at com.Test.subRMark_to_win(Test.java:16)
at com.Test.main(Test.java:26)
子程序的finally
public class Test {
static void subRMark_to_win() {
try {
System.out.println("子程序");
return;
}
finally {
System.out.println("子程序的finally");
}
}
public static void main(String args[]) {
try {
subRMark_to_win();
} catch (Exception e) {
System.out.println("主程序的catch");
}
System.out.println("马克-to-win:优雅结束");
}
}
public class Test {
public static void main(String[] args) {
int userInput=0;
int I = 6 / userInput;
System.out.println("马克-to-win:优雅结束");
}
}
输出结果:
Exception in thread "main" java.lang.ArithmeticException: / by zero
at Test.main(Test.java:4)
例:1.1.2
public class Test {
public static void main(String[] args) {
try
{
int userInput=0;
int I = 6 / userInput;
}
catch(Exception e)
{
System.out.println(e);
}
System.out.println("马克-to-win:优雅结束");
}
}
输出结果:
java.lang.ArithmeticException: / by zero例:1.1.3
public class Test {
public static void main(String[] args) {
try
{
int userInput=0;
int I = 6 / userInput;
}
catch(ArithmeticException e)
{
System.out.println(e);
}
System.out.println("马克-to-win:优雅结束");
}
}
输出结果:
java.lang.ArithmeticException: / by zero例:1.2.2
public class Test {
public static void main(String[] args) {
int arg1;
int result;
String s="12";
try {
arg1 = Integer.parseInt(s);
result = arg1 /0;
System.out.println("try中完成finish");
}
catch (NumberFormatException e) {
System.out.println("输入参数必须为整数!");
}
System.out.println("马克-to-win:优雅结束");
}
}
输出结果:
Exception in thread "main" java.lang.ArithmeticException: / by zeropublic class Test {
public static void main(String[] args) {
int arg1;
int result;
String s="12";
try {
arg1 = Integer.parseInt(s);
result = arg1 /0;
System.out.println("try中完成finish");
}
catch (NumberFormatException e) {
System.out.println("输入参数必须为整数!");
} catch (ArithmeticException e) {
System.out.println("除数不能为0");
}
System.out.println("马克-to-win:优雅结束");
}
}
结果如下:
除数不能为0例:1.5.1
public class Test {
public static void main(String[] args) {
int mark_to_win = 0;
int c;
if (mark_to_win == 0) throw new ArithmeticException("divide by 0");
else c=8/mark_to_win;
System.out.println("马克-to-win:优雅结束");
}
}
输出结果:
Exception in thread "main" java.lang.ArithmeticException: divide by 0
at Test.main(Test.java:5)
例:1.5.2
public class Test {输出结果:
Exception in thread "main" java.lang.ArithmeticException: / by zero例:1.5.3
public class Test {
public static void main(String[] args) {
int mark_to_win = 0;
int c;
try{
if (mark_to_win == 0) throw new ArithmeticException("divide by 0");
else c=8/mark_to_win;
}catch(ArithmeticException a)
{
System.out.println(a);
}
System.out.println("马克-to-win:优雅结束");
}
}
输出结果:
java.lang.ArithmeticException: divide by 0
马克-to-win:优雅结束
例:1.6.1
public class Test {
void m1_mark_to_win() {
throw new RuntimeException("divide by 0");
}
public static void main(String[] args) {
Test t=new Test();
t.m1_mark_to_win();
}
}
输出结果:
Exception in thread "main" java.lang.RuntimeException: divide by 0例:1.6.2(编译报错,不能运行)
public class Test {
void m1_mark_to_win() {
throw new FileNotFoundException();
}
public static void main(String[] args) {
Test t=new Test();
t.m1_mark_to_win();
}
}
例:1.6.3
import java.io.FileNotFoundException;
public class Test {
void m1_mark_to_win() {
try {
throw new FileNotFoundException();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
Test t=new Test();
t.m1_mark_to_win();
System.out.println("马克-to-win:优雅结束");
}
}
输出结果:
java.io.FileNotFoundException例:1.7.1(本例编译有错误)
import java.io.FileNotFoundException;
public class Test {
void m1_mark_to_win() {
throw new FileNotFoundException();
}
}
马 克-to-win:上例编译有错误,因为FileNotFoundException是checked异常, 所以我们必须加catch马上处理或用throws留待将来处理。catch我们这里就不说了。马克-to-win:上节有论述。我们这里用throws 来处理。
例:1.7.2(可通过编译)
import java.io.FileNotFoundException;
public class Test {
void m1_mark_to_win() throws FileNotFoundException {
throw new FileNotFoundException();
}
}
例:1.7.2_2(可通过编译)
import java.io.*;这里FileNotFoundException是IOException 的子类。
java.lang.Object
java.lang.Throwable
java.lang.Exception
java.io.IOException
java.io.FileNotFoundException
马 克-to-win:注意:例:1.7.2,编译就没问题了,但是throws FileNotFoundException,只是标记了一下问题,并没有真正处理,运行到throw new FileNotFoundException();时,程序还是会崩溃。马克-to-win:不信,下面我们就加一个主调方法测试一下。
例:1.7.3(本例编译有问题)
import java.io.FileNotFoundException;
public class Test {
void m1_mark_to_win() throws FileNotFoundException {
throw new FileNotFoundException();
}
public static void main(String[] args) {
Test t=new Test();
t.m1_mark_to_win();
System.out.println("马克-to-win:优雅结束");
}
}
马 克-to-win:例:1.7.3的主调方法t.m1_mark_to_win();又有问题了,因为被调方法m1_mark_to_win()里面有一 个没有处理的throw异常,所以主调方法还是编译不过。马克-to-win:我们必须或者catch或者throws处理,catch上一节讲了,现在 我们不讲。这里我们用throws,等于还是没有处理,程序运行到这还是会崩溃。马克-to-win:下面我们看一下运行结果。
例:1.7.4
import java.io.FileNotFoundException;
public class Test {
void m1_mark_to_win() throws FileNotFoundException {
throw new FileNotFoundException();
}
public static void main(String[] args) throws FileNotFoundException {
Test t=new Test();
t.m1_mark_to_win();
System.out.println("马克-to-win:优雅结束");
}
}
输出结果:
Exception in thread "main" java.io.FileNotFoundException
at Test.m1_mark_to_win(Test.java:4)
at Test.main(Test.java:8)
例:1.7.5
import java.io.FileNotFoundException;
public class Test {
void m1_mark_to_win() throws FileNotFoundException {
throw new FileNotFoundException();
}
public static void main(String[] args) {
Test t=new Test();
try {
t.m1_mark_to_win();
} catch (FileNotFoundException e) {
System.out.println(e);
}
System.out.println("马克-to-win:优雅结束");
}
}
输出结果:
java.io.FileNotFoundException例:1.7.6
import java.io.FileNotFoundException;输出结果:
Exception in thread "main" java.io.FileNotFoundException
例:1.8.1
import java.io.IOException;
class Animal{
void call() throws IOException
{
System.out.println("Animal");
}
}
class Dog extends Animal{
void call() throws IOException
{
System.out.println("Dog");
}
}
class Collie extends Dog{
void call() throws IOException
{
System.out.println("Collie");
}
}
class CallerMark_to_win {
void test(Animal a)
{
try {
a.call();
} catch (IOException e) {
System.out.println("捕获到IOException");
}
}
}
public class Test {
public static void main(String args[]) throws IOException {
CallerMark_to_win s = new CallerMark_to_win();
Dog d = new Dog();
Collie c=new Collie();
s.test(d);
s.test(c);
}
}
输出结果:
Dogimport java.io.IOException;
import java.sql.SQLException;
class Animal{
void call() throws IOException, SQLException
{
System.out.println("Animal");
throw new IOException();
}
}
class Dog extends Animal{
void call() throws IOException, SQLException
{
System.out.println("Dog");
throw new IOException();
}
}
class Collie extends Dog{
void call() throws IOException, SQLException
{
int a=8;
System.out.println("Collie");
if(a>4) throw new SQLException();
if(a>4) throw new IOException();
}
}
class CallerMark_to_win {
void test(Animal a)
{
try {
a.call();
} catch (IOException e) {
System.out.println("捕获到IOException");
} catch (SQLException e) {
System.out.println("捕获到SQLException");
}
}
}
public class Test {
public static void main(String args[]) {
CallerMark_to_win s = new CallerMark_to_win();
Dog d = new Dog();
Collie c=new Collie();
s.test(d);
s.test(c);
System.out.println("马克-to-win:优雅结束");
}
}
结果输出:
Dog例1.8.5(正确)
import java.io.*;
import java.sql.SQLException;
class Superclass {
void superMethod() throws IOException, SQLException {
}
}
class Subclass extends Superclass {
void superMethod() throws IOException, ArithmeticException,
FileNotFoundException, SQLException {
}
}
这里FileNotFoundException是IOException 的子类。
java.lang.Object
java.lang.Throwable
java.lang.Exception
java.io.IOException
java.io.FileNotFoundException
例1.9.1
public class Test {
public static void main(String args[]) throws RelationshipExceptionMark_to_win {
int talkTimesPerDay = 2;
if (talkTimesPerDay < 3) {
RelationshipExceptionMark_to_win e = new RelationshipExceptionMark_to_win();
e.setMsg("每天说话小于3 次,抛出关系异常的异常,分手");
throw e;
}
System.out.println("马克-to-win:优雅结束");
}
}
class RelationshipExceptionMark_to_win extends Exception {
String msg;
String getMsg() {
return msg;
}
void setMsg(String msg) {
this.msg = msg;
}
}
输出结果:
Exception in thread "main" RelationshipExceptionMark_to_win
at Test.main(Test.java:5)
public class Test {
public static void main(String args[]) {
int talkTimesPerDay = 2;
if (talkTimesPerDay < 3) {
RelationshipExceptionMark_to_win e = new RelationshipExceptionMark_to_win();
e.setMsg("每天说话小于3 次,抛出关系异常的异常,分手");
throw e;
}
System.out.println("马克-to-win:优雅结束");
}
}
class RelationshipExceptionMark_to_win extends RuntimeException {
String msg;
String getMsg() {
return msg;
}
void setMsg(String msg) {
this.msg = msg;
}
}
输出结果:
Exception in thread "main" RelationshipExceptionMark_to_win
at Test.main(Test.java:5)
例1.9.3
public class Test {输出结果:
每天说话小于3 次,抛出关系异常的异常,分手
马克-to-win:优雅结束
例: 1.10.1(try catch全齐,正常情况)
public class Test {
public static void main(String[] args) {
try
{
int userInput=0;
int I = 6 / userInput;
}
catch(Exception e)
{
System.out.println(e);
}
finally
{
System.out.println("in finally");
}
System.out.println("马克-to-win:优雅结束");
}
}
输出结果:
java.lang.ArithmeticException: / by zero
in finally
马克-to-win:优雅结束
例: 1.10.2(异常没有发生)
public class Test {
public static void main(String[] args) {
try
{
int userInput=2;
int I = 6 / userInput;
}
catch(Exception e)
{
System.out.println(e);
}
finally
{
System.out.println("in finally");
}
System.out.println("马克-to-win:优雅结束");
}
}
public class Test {
public static void main(String[] args) {
try
{
int userInput=2;
int I = 6 / userInput;
}
finally
{
System.out.println("in finally");
}
System.out.println("马克-to-win:优雅结束");
}
}
输出结果:
in finally
马克-to-win:优雅结束
public class Test {
public static void main(String[] args) {
try {
String str = null;
str = str.toUpperCase();
} catch (ArithmeticException e) {
System.out.println(e);
}
finally {
System.out.println("here is in final block.");
}
System.out.println("马克-to-win:优雅结束");
}
}
输出结果:
here is in final block.
Exception in thread "main" java.lang.NullPointerException
at Test.main(Test.java:5)
public class Test {
static void subRMark_to_win() {
try {
System.out.println("子程序");
int a=1/0;
}
finally {
System.out.println("子程序的finally");
}
}
public static void main(String args[]) {
try {
subRMark_to_win();
} catch (Exception e) {
System.out.println("主程序的catch");
}
System.out.println("马克-to-win:优雅结束");
}
}
输出结果:
子程序
子程序的finally
主程序的catch
马克-to-win:优雅结束
public class Test {
static void subRMark_to_win() {
try {
System.out.println("子程序");
throw new RuntimeException();
}
finally {
System.out.println("子程序的finally");
}
}
public static void main(String args[]) {
try {
subRMark_to_win();
} catch (Exception e) {
System.out.println("主程序的catch");
}
System.out.println("马克-to-win:优雅结束");
}
}
例: 1.10.7(try代码中有return)
public class Test {
static void subRMark_to_win() {
try {
System.out.println("子程序");
return;
}
finally {
System.out.println("子程序的finally");
}
}
public static void main(String args[]) {
try {
subRMark_to_win();
} catch (Exception e) {
System.out.println("主程序的catch");
}
System.out.println("马克-to-win:优雅结束");
}
}