Java异常:
任何一种程序设计语言设计的程序在运行时都有可能出现错误,例如除数为0,数组下标越界,要读写的文件不存在等等。
捕获错误最理想的是在编译期间,但有的错误只有在运行时才会发生。
对于这些错误,一般有两种解决方法:
遇到错误就终止程序的运行。
由程序员在编写程序时,就考虑到错误的检测、错误消息的提示,以及错误的处理。
常见的异常:
- RuntimeException
– 错误的类型转换
– 数组下标越界
– 空指针访问
- IOExeption
– 从一个不存在的文件中读取数据
– 越过文件结尾继续读取
– 连接一个不存在的URL
* 异常的由来:问题也是现实生活中具体的事物,也可以通过java的类的形式进行描述,并封装成对象。
* 其实就是java对不正常情况进行描述后的对象体现。
*
* 对于问题的划分分为两种:一种是严重的问题,一种是非严重的问题。
* 对于严重的问题,java通过Error类进行描述。JVM系统内部错误、资源耗尽等严重情况
* 对于Error一般不编写针对性的代码。
*
* 对于非严重的问题,java通过Exception类进行描述。空指针访问、试图读取不存在的文件、网络连接中断
* 对于Exception可以使用针对性的处理方式进行处理。
*
* 无论Error或者Exception都具有一些共性内容。
* 例如:不正常情况的信息、引发原因等。
*
* 不断向上抽取,抽取出来的父类就叫做Throwable(可抛出的),下面两个子类。Throwable(可抛出的)
|--Error:通常出现重大问题如:运行的类不存在或者内存溢出等。
|--Exception:在运行时运行出现的一起情况,可以通过try catch finally
*
* 2.异常的处理。
* java提供了特有的语句进行处理。
* try
* {
* 需要被检测的代码。
* }
*
* catch (异常类 变量名)
* {
* 处理异常的代码(处理方式)
* }
*
* finally
* {
* 一定会执行的语句。一般用来关闭资源
* }
*
* 3.对捕获到的异常对象进行常见的方法操作。
* getMessage() 获取异常的信息。
* toString() 异常名字:异常信息
* e.printStackTrace(); 异常名称:异常信息:异常类名:异常出现的位置
*
* 在函数上声明异常。
* 便于提高安全性,让调用处进行处理,不处理则编译失败。
*
* 对多异常的处理。
* 1.声明异常时,建议声明更为具体的异常,这样处理得可以更具体。
* 2.对方声明几个异常就对应几个catch块。不要定义多余的catch块。
* 如果多个catch块中的异常出现继承关系,父类异常catch块放在最下面。
*
* 建议在进行catch处理时,catch中一定要定义具体的处理方式。不要简单的定义一句e.printStackTrace();
* 也不要简单的就写一条输出语句。
* */
//Demo类
class Demo
{
//除法函数,需要调用者传入两个参数
public int ChuFa(int a, int b)
{
return a / b;
}
}
//异常测试类
public classExceptionDemo
{
public static void main(String[] args)
{
//创建Demo类的实例对象
Demo d = new Demo();
//try catch语句
try
{
//可能会产生异常的代码
int x = d.ChuFa(5, 0);
System.out.println(x);
}
//捕捉异常
catch(Exception e)
{
//处理异常
System.out.println("除零了,非法操作!");
System.out.println(e.getMessage()); // /by Zero异常信息
System.out.println(e.toString()); // java.lang.ArithmeticException:/ by zero
//异常名字:异常信息
e.printStackTrace(); //异常名称:异常信息:异常类名:异常出现的位置
//其实jvm默认的异常处理机制,就是在调用printStackTrace()方法,打印异常的堆栈的跟踪信息。
}
System.out.println("over");
}
}
- Java提供的是异常处理的抓抛模型。
- Java程序的执行过程中如出现异常,会自动生成一个异常类对象,该异常对象将被提交给Java运行时系统,这个过程称为抛出(throw)异常。
- 如果一个方法内抛出异常,该异常会被抛到调用方法中。如果异常没有在调用方法中处理,它继续被抛给这个调用方法的调用者。这个过程将一直继续下去,直到异常被处理。这一过程称为捕获(catch)异常。
- 如果一个异常回到main()方法,并且main()也不处理,则程序运行终止。
- 程序员通常只能处理Exception,而对Error无能为力。
- 在开发时,如果定义功能时,发现该功能会出现一些问题,应该将问题在定义功能时标示出来,这样调用者就可以在使用这个功能的时候,预先给出处理方式。
- 如何标示呢?通过throws关键字完成,格式:throws异常类名,异常类名...
- 这样标示后,调用者,在使用该功能时,就必须要处理,否则编译失败。
- 处理方式有两种:1、捕捉;2、抛出。
- 对于捕捉:java有针对性的语句块进行处理。
- 异常分两种:
- 1:编译时被检查的异常,只要是Exception及其子类都是编译时被检测的异常。
- 2:运行时异常,其中Exception有一个特殊的子类RuntimeException,以及RuntimeException的子类是运行异常,也就说这个异常是编译时不被检查的异常。
- 编译时被检查的异常和运行时异常的区别:
- 编译被检查的异常在函数内被抛出,函数必须要声明,否编译失败。
- 声明的原因:是需要调用者对该异常进行处理。
- 运行时异常如果在函数内被抛出,在函数上不需要声明。
- 不声明的原因:不需要调用者处理,运行时异常发生,已经无法再让程序继续运行,所以,不让调用处理的,直接让程序停止,由调用者对代码进行修正。
- 定义异常处理时,什么时候定义try,什么时候定义throws呢?
- 功能内部如果出现异常,如果内部可以处理,就用try;
- 如果功能内部处理不了,就必须声明出来,让调用者处理。
- 声明抛出异常是Java中处理异常的第二种方式
- 如果一个方法(中的语句执行时)可能生成某种异常,但是并不能确定如何处理这种异常,则此方法应显式地声明抛出异常,表明该方法将不对这些异常进行处理,而由该方法的调用者负责处理。
- 在方法声明中用 throws 子句可以声明抛出异常的列表,throws后面的异常类型可以是方法中产生的异常类型,也可以是它的父类。
自定义异常:
因为项目中会出现一些特有的问题。而这些问题并未被java所描述并封装对象。
* 所以对这些特有的问题可以按照java对待问题封装的思想。将特有的问题进行自定义的异常封装。这个异常,称为自定义异常。
对于除法运算,0作为除数是不可以的。java中对这种问题用ArithmeticException类进行描述。对于这个功能,在我们项目中,除数除了不可以为0外,还不可以为负数。可是负数的部分java并没有针对描述。所以我们就需要自定义这个异常。
自定义异常的步骤:
1:定义一个子类继承Exception或RuntimeException,让该类具备可抛性。
2:通过throw或者throws进行操作。
//自定义一个负数异常
classFuShuException extends Exception
{
//空参数构造函数
public FuShuException() {}
//
int value;
public FuShuException(String message, intvalue)
{
super(message);
this.value = value;
}
public int getValue()
{
return value;
}
}
异常的转换思想:当出现的异常是调用者处理不了的,就需要将此异常转换为一个调用者可以处理的异常抛出。
这种情况,如果出现异常,并不处理,但是资源一定关闭,所以try finally集合只为关闭资源。
记住:finally很有用,主要用户关闭资源。无论是否发生异常,资源都必须进行关闭。
System.exit(0);//退出jvm,只有这种情况finally不执行。
当异常出现后,在子父类进行覆盖时,有了一些新的特点:
1:当子类覆盖父类的方法时,如果父类的方法抛出了异常,那么子类的方法要么不抛出异常要么抛出父类异常或者该异常的子类,不能抛出其他异常。
2:如果父类抛出了多个异常,那么子类在覆盖时只能抛出父类的异常的子集。
注意:
如果父类或者接口中的方法没有抛出过异常,那么子类是不可以抛出异常的,如果子类的覆盖的方法中出现了异常,只能try不能throws。
如果这个异常子类无法处理,已经影响了子类方法的具体运算,这时可以在子类方法中,通过throw抛出RuntimeException异常或者其子类,这样,子类的方法上是不需要throws声明的。
package包:
/* 建议定义包名可以使用URL来完成定义,URL一般都是唯一的,不会重复。
例如:com.itheima.javase
* 包与包之间进行访问,被访问的包中的类以及类中的成员,需要public修饰。
* 不同宝中的子类可以直接访问父类中被proteceed权限修饰的成员。
* 包与包之间可以使用的权限只有两种,public和protected。
* 权限从大到小排为public、protected、default(默认什么都不写)、private
*
import导入:类名称变长,写起来很麻烦。为了简化类名的书写,使用一个关键字,import。import导入的是包中的类。* 通配符,可以导入指定包中所有的
类文件,建议不要使用通配符,需要用到包中的哪个类就导入哪个类。
例如:import java.util.*;导入util工具包下所有的类,建议不要这么干,
建议导入需要的类,import java.util.ArrayList;
如果导入的两个包中存在着相同名称的类。这时如果用到该类,必须在代码中指定包名。
jar包:
l Java的压缩包
• 方便项目的携带。
• 方便于使用,只要在classpath设置jar路径即可。
• 数据库驱动,SSH框架等都是以jar包体现的。
通过jar.exe工具对jar的操作。
• 创建jar包
• jar -cvf mypack.jar packa packb
• 查看jar包
• jar -tvf mypack.jar [>定向文件]
• 解压缩
• jar -xvf mypack.jar
• 自定义jar包的清单文件
• jar –cvfm mypack.jar mf.txt packa packb