首页 > 代码库 > 【Java基础】05_异常&File

【Java基础】05_异常&File

一、异常引言

程序出现的不正常的情况。异常就是Java程序在运行过程中出现的错误。

问题也是现实生活中一个具体事物,也可以通过java 的类的形式进行描述,并封装成对象。其实异常就是Java对不正常情况进行描述后的对象体现。

 

二、异常继承体系图解

 

技术分享

三、异常的体系

java.lang.Throwable

|--Error    严重问题,我们不处理。要改正代码。

通常出现重大问题如:运行的类不存在或者内存溢出等。
是不需要增加代码处理(try...catch)的。代码本身有问题。

一般这种情况是需要修改代码的。一般的处理方案是加内存,将这类补上来。

|--Exception

        |--RuntimeException    

运行期异常,我们也不处理(try...catch)。代码不够严谨,我们需要修正代码。

比如:传递的参数(别人传过来)。参数类型不正确等,非空校验?

        |--RuntimeException

编译期异常,即编写代码报红×的,必须处理的,否则程序编译不通过

将来有可能出现的异常情况。

隐含的问题,不管怎么修改代码都会隐含,必须处理

 

编译时异常和运行时异常的区别

Java中的异常被分为两大类:编译时异常和运行时异常。

所有的RuntimeException类及其子类的实例被称为【运行时异常】,

其他的非RuntimeException异常及其子类就是【编译时异常】

 

【编译时异常】

    Java程序必须显示处理( try catch throws),否则程序就会发生错误,无法通过编译

【运行时异常】

    无需显示处理,也可以和编译时异常一样处理,可处理可不处理。

声明抛出为RuntimeException的方法被其他对象调用时,是不需要try...catch或者throws的。即使声明了,再调用时也是不需要处理。

    代码不够严谨,我们需要修正代码。

 

注意:        

每种体系的子类都是以父亲的名称作为后缀。

* XxxError

* XxxException

四、异常的处理:

A:JVM的默认处理方式

如何程序出现了问题,我们没有做任何处理,最终jvm会做出默认的处理。

把异常的名称,原因,位置等【信息输出在控制台】,同时会【结束程序】。

一旦有异常发生,【其后来的代码不能继续执行】。

举例:

Exception in thread "main" java.lang.ArithmeticException: / by zero

【其后来的代码不能继续执行】。

B:如果程序有异常,我们自己怎么手动解决呢?

方式a:编写处理代码try...catch...finally

 

自己编写处理代码后,即使发生了异常,后面的程序可以继续执行

基本格式:

try{

    可能发生异常的代码; (包裹的代码越少效率越高)

}catch(异常类名 变量名){

    异常的处理代码;

    //处理完后,异常代码其下面的代码可以继续操作

    //,实际开发中返回一个错误页面。

}finally{

    释放资源的代码;

}

变形格式:

1try...catch            

try {

    可能出现问题的代码;

}catch(异常名 变量) {

    针对问题的处理;

}

2try...catch...catch

3try...catch...finally

4try...catch...catch...finally

5try...finally

注意

A:try里面的代码越少越好

B:catch里面必须有内容,哪怕是给出一个简单的提示(如输出语句或者e.printStackTrace())

C:一旦try代码块中有异常发生,匹配到catch中的异常类型,就会立马执行catch里面的代码。

1.一旦try里面出了问题,jvm会帮我们生成一个异常对象,然后把这个对象抛出,

然后和catch里面的问题进行匹配,

2.一旦有匹配的该对象类型,就执行catch里面的处理信息,然后结束了try...catch

继续执行该try...catch后面的语句。

一个代码中,有多个异常问题,怎么解决呢?

A:一个个用异常处理方案解决。            

每一个问题写一个try...catch

try{

    可能出现问题的代码;

}catch(异常类名 变量名){

    针对问题的处理;

}

try{

...

}catch( ){

...

}

......

 

B:针对所有问题,写一个try...多个catch代码。

写一个try,多个catch

try{

    ...

}catch(异常类名 变量名) {

    ...

}catch(异常类名 变量名) {

    ...

}

......

 

注意事项

1:能明确的异常类型尽量明确,不要用大的异常类型来处理。

2:平级关系的异常catch谁前谁后无所谓,

    如果多个异常出现了子父关系,父异常【必须】在后面。

    否则,因为多态,永远匹配不到子异常。

 

JDK7针对多个catch进行了优化:

    多个catch用一个catch替代。不是指多个catch的内容,用一个Exception处理。

    格式:

catch(异常1 | 异常2 | 异常3 ... 变量){...}

    注意:

        A:处理方式是一致的。(实际开发中,好多时候可能就是针对同类型的问题,给出同一个处理)

B:这些异常必须是平级关系。

        try...catch...catch的不同点是:

        JDK7的这种方案是必须平级关系,不能有子父关系。

        try...catch...catch父亲放最后是可以的

最终的标准代码格式

基本格式:标准代码

try{

    可能有问题的代码

}catch(异常类名 变量名){

    处理方案↓:

    变量名.printStackTrace();

}finally{

    释放资源。(数据库,IO)

}

 

finally:里面代码永远会执行。但有特殊情况。

如果在执行到finally之前jvm退出了(System.exit(int number)),就不能执行了。

方式b:抛出 throws        

把自己处理不了的,在方法上声明,告诉调用者,这里有问题调用者去处理该异常。

【出错后下面的代码不在继续执行】。

try catch处理后,出错位置后面的代码还是会执行的

 

处理方式:用throws关键字在方法上声明(抛出异常)

c:到底使用谁?    

a:能自己处理的尽量自己处理。(建议用try...catch)

b:实在不行,你先抛了在说。其实我们对异常是进行统一处理的。

看到问题,于问题提示处或者行号位置点击鼠标,提示解决方案

点击左边红X即可。处理方案就出来了实际开发用第二种try...catch

 

五、自定义异常

java虽然已经考虑到了很多种异常情况,但是,有些需求java程序是考虑不到的。

比如说:我要求学生的分数不能为负数。那么,针对这种情况,我们就要编写自定义异常类进行处理。

    

如何编写一个自定义异常类呢?

就是自定义一个类,继承自Exception或者RuntimeException,

【只需要提供无参构造和一个带参构造即可】

【开发中】:一般继承自RuntimeException

异常的注意实现    

A:子类重写父类方法时,子类的方法必须抛出相同的异常或父类异常的子类。

(父亲坏了,儿子不能比父亲更坏)

B:如果父类抛出了多个异常,子类重写父类时,

只能抛出相同的异常或者是他的子集,子类不能抛出父类没有的异常

C:如果被重写的方法没有异常抛出,

那么子类的方法绝对不可以抛出异常,

如果子类方法内有异常发生,那么子类只能try...catch,不能throws

六、java.io.File类(掌握)

引言

* 我们要想实现IO的操作,就必须知道硬盘上文件的表现形式。

* Java就提供了一个类File供我们使用。

概述

IO流操作中,大部分都是对文件的操作,所以Java就提供了File类供我们来操作文件。

public class File extends Object implements Serializable, Comparable<File>

 

File是【文件】和【目录】路径名的抽象表示形式

直接打印file,打印出路径,说明重写了toString()方法

IO用于在设备间进行数据传输的操作

IO流分类:

A:流向        

输入流    读取数据

输出流    写出数据

B:数据类型

字节流    

    字节输入流

    字节输出流

字符流

    字符输入流

    字符输出流

注意:

    a:如果我们没有明确说明按照什么分,默认按照数据类型分。

    b:除非文件用windows自带的记事本打开我们能够读懂,才采用字符流,否则建议使用字节流。

构造方法

A:File(String pathname)

根据一个路径字符串得到File对象

    举例:File file = new File("e:\\demo\\a.txt"); // 【常用方式】

B:File(String parent, String child):

根据一个目录和一个子文件/目录得到File对象

    举例:File file = new File("e:\\demo","a.txt");

C:File(File parent, String child):

根据一个父File对象和一个子文件/目录得到File对象

举例:

File file = new File("e:\\demo");

File file2 = new File(file,"a.txt");

注意:

三个构造方法的效果都一样

引用变量仅仅是一个路径的表示,不代表具体的路径一定是存在的。

功能方法

A:创建功能    

创建文件:

    public boolean createNewFile()

    如果指定的文件不存在,就创建,返回true

    如果存在这样的文件, 就不创建,返回false

创建文件夹:

    public boolean mkdir()

    创建文件夹 如果存在这样的文件夹,就不创建了

    创建多级目录 如果想创建一个指定的目录或者文件,要求,父目录必须存在。

    

    public boolean mkdirs() // 【常用方式】

    创建文件夹,如果存在,就不创建。

    这个时候,如果父文件夹不存在,它也会自动创建

注意:

你要创建什么,自己最清楚。

    也就是,你要调用哪个方法,你自己必须明白

    因为如果你不明白,就会有问题。

 

绝对路径与相对路径

绝对路径:以盘符开始的路径

相对路径:不以盘符开始的路径。

        除非你知道相对于那个文件夹。为了方便,会使用。

 

如果你创建文件或者文件夹忘了写盘符路径,那么,默认在项目路径下。

    "file.txt"可以是一个文件名,也可以是一个文件夹名。

 

书写格式错误:

盘符:后面没有双斜杠

    格式书写错误 F:后面没有双斜杠

    如果File对象的根目录( F)与当前项目所在盘符一致,那么就会在该程序或该程序包所在目录创建文件或文件夹。

    如果File对象的根目录( F)与当前项目所在盘符不一致,就会在该根目录下创建文件或文件夹(按正常理解即可)

B:删除功能    

public boolean delete():

既可以删除文件,也可以删除文件夹,取决于使用的对象

文件对象调用就删除文件;文件夹对象调用就删除文件夹

注意:

A:如果你删除的文件夹下还有内容,那么必须先把使用内容删除完毕后,在删除该文件夹

Bjava语言的删除不走回收站

C:重命名功能    

public boolean renameTo(File dest)

如果File路径名相同,就是改名。

如果File路径名不同,就是改名并剪切到目的路径。

D:判断功能【常用·掌握】

public boolean exists()

判断file对象是否存在(此抽象路径名表示的文件或目录是否存在。)

public boolean isFile()

判断file对象是否是文件

public boolean isDirectory()

判断file对象是否是文件夹

public boolean isAbsolute()

判断file对象是否是绝对路径

public boolean canRead()    // windows下默认所有文件都是可读的

判断file对象是否可读

public boolean canWrite()

判断file对象是否可写

public boolean isHidden()

判断file对象是否隐藏

 

注意:

File对象路径中文件或文件夹不存在时,全部返回false

如果存在的话,根据文件或者文件夹的实际属性返回实际的值

E:获取功能【】

获取file对象的绝对路径            

public String getAbsolutePath()

获取相对路径

public String getPath()

获取文件名称

public String getName()

获取文件的大小,单位是字节

public long length()

获取上次修改时间的毫秒值

public long lastModified()

 

注意:

文件或文件夹存不存在都会根据file对象返回对象的属性

F:高级获取功能

public static File[] listRoots()

列出可用的系统文件根目录 c:\\ 或者 d:\

无须关联file,电脑本身存在与File中的参数无关

 

返回的是指定目录下所有文件或者文件夹的【文件名称数组】

public String[] list()

 

返回的是指定目录下所有文件或者文件夹【对象数组】

public File[] listFiles()

 

注意:对目录操作

G:文件名称过滤器接口FilenameFilter    

FilenameFilter 一般使用匿名内部类实现。

public String[] list(FilenameFilter filter)

文件名称过滤

public File[] listFiles(FilenameFilter filter)

看源码解析

boolean accept(File dir,String name)

指定文件路径是否应该包含在某一文件列表中。

    dir - 被找到的文件所在的目录。

    name - 文件的名称。

返回:

当且仅当该名称应该包含在文件列表中时返回 true

否则返回 false

String[] strArray = file.list(new FilenameFilter() {

    @Override

    public boolean accept(File dir, String name) {

        // return false;

        // return true;

        // 通过这个测试,我们就知道了,到底把这个文件或者文件夹的名称加不加到数组中,取决于这里的返回值是true还是false

        // 所以,这个的true或者false应该是我们通过某种判断得到的

        // System.out.println(dir + "---" + name);

        // File file = new File(dir, name);

        // // System.out.println(file);

        // boolean flag = file.isFile();

        // boolean flag2 = name.endsWith(".jpg");

        // return flag && flag2;

        return new File(dir, name).isFile() && name.endsWith(".jpg");

    }

});

 

【Java基础】05_异常&File