Check异常和Runtime异常体系
Java的异常被分为两大类,Check异常(检查期异常)和Runtime异常(编译时异常),所有的RuntimeException以及子类都被称为运行时异常,除了运行时异常的都是检查期异常。
其中运行时异常可以不用捕获,代码仍然能编译通过,检查期必须人工捕获,否则编译不通过。
public class ExceptionDemo {
/**
* Java的异常分为两大类:Check异常和Runtime异常
* Check检查期异常必须要进行捕获,否则编译无法通过
* Runtime运行时异常可以不需要进行捕获,编译也可正常通过
*/
public static void main(String[] args) {
System.out.println(9/0);//运行时异常:数学运算错误
try {
//检查期异常:需要人为进行捕获,或者是抛出指定异常,否则编译出错
FileInputStream fis = new FileInputStream("c://test.txt");
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
//测试常见的运行时异常
public class RuntimeExceptionTest {
public static void main(String[] args) {
/**
* 1.java.lang.NullPointerException
* 空指针异常:调用了未经初始化的对象或者是不存在的对象
* 数组的初始化是指对数组分配需要的空间,而初始化后的数组
* 对应的数组元素并没有被初始化(实例化),其依然还是空的,
* 所以调用的时候出现空指针异常
*/
int[] arr = null;
System.out.println(arr[0]);
/**
* 2.java.lang.ClassNotFoundException
* 指定的类不存在
*/
/**
* 3. java.lang.ArithmeticException:
* / by zero -->数学运算异常
*/
System.out.println(1/0);
/**
* 4.java.lang.ArrayIndexOutOfBoundsException
* 数组下标越界异常(数组下标的取值范围为0->length-1)
*/
String[] s = new String[3];
System.out.println(s[3]);
/**
* 5.java.lang.lllegalArgumentException
* 方法参数错误异常
* 调用类库的方法时出现参数传递错误
*/
/**
* 6.java.lang.lllegalAccessException
* 没有访问权限
* 当应用程序要调用一个类,但当前的方法没有对该类的访问权限,则会出现这个异常
*/
}
}
1.使用throws声明抛出异常
public class ThrowsExceptionTest {
public static void main(String[] args) {
/**
* 如果是要调用一个抛出异常的方法,可以有两种处理方式
* 1.直接在本方法中处理异常
* 2.继续向上一级抛出指定异常(throws 异常)
*/
try {
test();
} catch (IOException e) {
System.out.println("捕获到文件不存在异常...");
} catch (SQLException e) {
e.printStackTrace();
}
}
/**
* 在方法声明处抛出异常使用“throws”关键字
* 如果是抛出多个异常则可用 “,”进行分隔
*/
public static void test() throws IOException,SQLException
{
FileInputStream fis = new FileInputStream("c://test.txt");
}
}
子类继承父类
- 子类重写父类的方法 那么抛出的异常必须比父类更小,更少的异常。
- 两小原则针对的是检查期异常,而运行期异常无关
/**
* 子类在重写父类的方法时要遵循“两小原则”
* 子类抛出的异常要比父类小
* 子类抛出的异常要比父类少
* “两小原则”是针对检查期异常而言的,与运行时异常无关
*/
class Father
{
public static void test()throws IOException,SQLException
{
FileInputStream fis = new FileInputStream("c://test.txt");
}
}
public class OverrideExceptionDemo extends Father{
public static void test()throws IOException,SQLException
{
FileInputStream fis = new FileInputStream("c://test.txt");
}
public static void main(String[] args) {
try {
test();
} catch (IOException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
2.使用throw抛出异常
如果需要在程序中自行抛出异常,则使用throw进行抛出异常
public class ThrowExceptionTest {
public static void main(String[] args) {
// testThrow(-1);
try {
testThrow2(-2);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void testThrow(int i)
{
/**
* 如果参数i满足某些条件则手动利用“throw”关键字抛出异常
* 但在方法声明处需要再次进行声明
*/
if(i<0)
{
//自行抛出RuntimeException或者其子类
throw new RuntimeException("i值小于0,不满足条件...");
}
}
public static void testThrow2(int i) throws Exception
{
if(i<0)
{
//自行抛出Exception,需要在方法声明处使用“throws”关键字再次抛出异常
throw new Exception("i值小于0,不满足条件...");
}
}
}
关键字throw与throws的区别
如果调用一个抛出异常的方法 那么调用者有两种处理方式
1.在本方法内处理
2.继续向上一级抛出 throws IOException
如果需要在程序中自行抛出异常,则使用throw进行抛出异常
throws是方法可能抛出异常的声明。(用在声明方法时,表示该方法可能要抛出异常)
区别:
- throws出现在方法函数头;而throw出现在函数体。
- throws表示出现异常的一种可能性,并不一定会发生这些异常;throw则是抛出了异常,执行throw则一定抛出了某种异常对象。
- 两者都是消极处理异常的方式(这里的消极并不是说这种方式不好),只是抛出或者可能抛出异常,但是不会由函数去处理异常,真正的处理异常由函数的上层调用处理。