菜鸟之路Day14一一异常与File

简介: 此篇博客详细介绍了Java中的异常处理机制和File类的常用操作。

菜鸟之路Day14一一异常与File

作者:blue

时间:2025.2.2

1.异常

1.1异常体系

image-20250202111339143.png

Error:代表的系统级别错误(属于严重问题)系统一旦出现问题,sun公司会把这些错误封装成Error对象。Error是给sun公司自己用的,不是给我们程序员用的。因此我们开发人员不用管它。

Exception:叫做异常,代表程序可能出现的问题。我们通常会用Exception以及它的子类来封装程序出现的问题

运行时异常:RuntimeException及其子类,编译阶段不会出现异常提醒。运行时出现的异常(如:数组索引越界异常)

编译时异常:直接继承于Excpetion,编译阶段就会出现异常提醒。(如:日期解析异常)

1.2异常的作用

作用一:异常时用来查询bug的关键参考信息

作用二:异常可以作为方法内部的一种特殊返回值,以便通知调用者底层的执行情况

1.3异常的处理方式

①JVM默认的处理方式

​ 把异常的名称,异常原因及异常出现的位置等信息输出在了控制台

​ 程序停止执行,下面的代码不会再执行了

②自己处理(捕获异常)

try {
    可能出现异常的代码;
} catch(异常类名 变量名) {
    异常的处理代码;
}

目的:当代码出现异常的时候,可以让程序继续往下执行

public class Demo1 {
   
    public static void main(String[] args) {
   

        int[] arr = {
   1,2,3,4,5,6};
        try{
   
            //可能出现异常的代码
            System.out.println(arr[10]);//此处出现了异常,程序就会创建ArrayIndexOutOfBoundsException对象
                                        //new ArrayIndexOutOfBoundsException();
                                        //拿着这个对象到catch的小括号中对比,看括号中的变量是否可以接受对象
                                        //如果能被接受,就表示该异常被捕获(抓住),执行catch里面对应的代码
                                        //当catch里面的代码执行完毕,继续执行try...catch体系下面其他代码
        }catch(ArrayIndexOutOfBoundsException e){
   
            //如果出现了ArrayIndexOutOfBoundsException异常,我该如何处理
            System.out.println("索引越界了");
        }

        System.out.println("看看我执行了吗?");
    }
}

有关捕获异常的四个问题

一.如果try中没有遇到问题,怎么执行?

public class Demo1 {
   
    public static void main(String[] args) {
   

        int[] arr = {
   1,2,3,4,5,6};
        try{
   
            //正常的代码
            System.out.println(arr[0]);
        }catch(ArrayIndexOutOfBoundsException e){
   
            //如果出现了ArrayIndexOutOfBoundsException异常,我该如何处理
            System.out.println("索引越界了");
        }
        System.out.println("看看我执行了吗?");
    }
}

答:会把try里面的所有代码全部执行完毕,不会执行catch里面的代码,只有当出现了异常才会执行catch里面的代码

二.如果try中可能遇到多个问题,怎么执行?

public class Demo2 {
   
    public static void main(String[] args) {
   
        int[] arr = {
   1,2,3,4,5,6};
        try{
   
            System.out.println(arr[10]);
            System.out.println(2/0);
        }catch(ArrayIndexOutOfBoundsException e){
   
            //如果出现了ArrayIndexOutOfBoundsException异常,我该如何处理
            System.out.println("索引越界了");
        }catch (ArithmeticException e){
   
            System.out.println("不能做除0操作");
        }
        System.out.println("看看我执行了吗?");
    }
}

答:我们会写多个catch与之对应,如果我们要捕获多个异常,这些异常中如果存在父子关系的话,那么父类一定要写在下面,在JDK7之后,我们可以在catch中同时捕获多个异常,中间用|进行隔开,表示如果出现了A异常或者B异常,采取同一种处理方案。

三.如果try中遇到问题没有被捕获,怎么执行?

答:相当于try....catch的代码白写了,

四.如果try中遇到了问题,那么try下面的其他代码还会执行吗?

答:下面的代码不会执行了,直接跳转到对应的catch当中,执行catch里面的语句体,但是如果没有对应catch与之匹配,那么还是会交给虚拟机进行处理

③抛出异常

1.关于抛出异常的一些常用方法(Throwable的成员方法)

public class Demo3 {
   
    public static void main(String[] args) {
   
        /*
        *   public String getMessage()  返回此throwable的详细消息字符串
        *   public String toString()    返回此可抛出的简短描述
        *   public void printStackTrace() 把异常的错误信息输出在控制台
        *                               细节:仅仅是打印信息,不会停止程序运行
        * */

        int[] arr = {
   1,2,3,4,5,6};
        try {
   
            System.out.println(arr[10]);
        } catch (ArrayIndexOutOfBoundsException e){
   
            /*String message = e.getMessage();
            System.out.println(message); Index 10 out of bounds for length 6 */

            /*String str = e.toString();
            System.out.println(str); java.lang.ArrayIndexOutOfBoundsException: Index 10 out of bounds for length 6*/

            e.printStackTrace();
        }
        System.out.println("看看我执行了吗?");
    }
}

2.抛出处理

①throws:写在方法定义处,表明声明一个异常,告诉调用者,使用本方法可能会有哪些异常

编译时异常:必须要写

运行时异常:可以不写

public void 方法()throws 异常类名1,异常类名2...{
   
    ...
}

②throw:写在方法内,结束方法

手动抛出异常对象,交给调用者

方法中下面的代码不再执行了

public void 方法(){
   
    throw new NullPointerException();
}

实例:

public class Demo4 {
   
    public static void main(String[] args) {
   
        int[] arr = null;
        int max = 0;
        try {
   
            max = getMax(arr);
        } catch (NullPointerException e) {
   
            System.out.println("空指针异常");
        } catch (ArrayIndexOutOfBoundsException e) {
   
            System.out.println("索引越界异常");
        }

        System.out.println(max);
    }
    public static int getMax(int[] arr){
   
        if(arr==null){
   
            //手动创建一个异常对象,并把这个异常交给方法调用者来处理
            //此时方法就会结束,下面的代码不会执行了
            throw new NullPointerException();
        }
        if(arr.length == 0){
   
            throw new ArrayIndexOutOfBoundsException();
        }
        int max = arr[0];
        for(int i=1;i<arr.length;i++){
   
            if(arr[i]>max) max = arr[i];
        }
        return max;
    }
}

练习:

需求:
键盘录入自己心仪的女朋友姓名和年龄。
姓名的长度在3~10之间
年龄的范围为18-40岁
超出这个范围是异常数据不能赋值,需要重新录入,一直录到正确为止。
提示
需要考虑用户在键盘录入时的所有情况。
比如:录入年龄时超出范围,录入年龄时录入了abc等情况

public class Demo5 {
   
    public static void main(String[] args) {
   
        GirlFriend gf = new GirlFriend();
        Scanner sc = new Scanner(System.in);
        while (true) {
   
            try {
   
                System.out.println("请输入你心仪女朋友的姓名");
                String name = sc.nextLine();
                gf.setName(name);//有可能出现错误
                System.out.println("请输入女朋友的年龄");
                String age = sc.nextLine();
                int Age = Integer.parseInt(age);//有可能出现错误
                gf.setAge(Age);//有可能出现错误
                break;
            } catch (NumberFormatException e) {
   
                System.out.println("年龄的格式有误,请输入数字");
            } catch (RuntimeException e) {
   
                System.out.println("姓名或年龄超出范围");
            }
        }
        System.out.println(gf);
    }
}

在GirlFriend类中,对set方法的数据做限定,如果不是正确数据,就抛出一个RuntimeException对象

public class GirlFriend {
   
    private String name;
    private int age;

    public GirlFriend() {
   
    }

    public GirlFriend(String name, int age) {
   
        this.name = name;
        this.age = age;
    }

    public String getName() {
   
        return name;
    }

    public void setName(String name) {
   
        if(name.length()<3||name.length()>10){
   
            throw new RuntimeException();
        }
        this.name = name;
    }

    public int getAge() {
   
        return age;
    }

    public void setAge(int age) {
   
        if(age<18||age>40){
   
            throw new RuntimeException();
        }
        this.age = age;
    }

    @Override
    public String toString() {
   
        return "GirlFriend{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

1.4自定义异常

在刚刚的练习代码中,我们针对名字和年龄的异常都是抛出一个RuntimeException,但不够具体,不够见名知意,这时我们就可以自定义异常。

①定义异常类

②写继承关系

③空参构造

④带参构造

意义:让控制台的报错信息更加见名知意

现在的idea建类的时候都有Exception选项

public class NameFormatException extends RuntimeException {
   
  public NameFormatException() {
   
  }

  public NameFormatException(String message) {
   
        super(message);
    }
}

然后我们修改对应的抛出错误的方法

public void setName(String name) {
   
     if(name.length()<3||name.length()>10){
   
           throw new NameFormatException(name+"姓名的长度在3~10之间");
     }
     this.name = name;
}

然后我们修改对应的catch异常的对象,调用方法把异常的错误信息输出在控制台即可

catch (NameFormatException e) {
   
       e.printStackTrace();
}

2.File

2.1构造方法

File对象就表示一个路径,可以是文件的路径,也可以是文件夹的路径

这个路径可以是存在的,也允许是不存在的

构造方法演示:

public class Demo1 {
   
    public static void main(String[] args) {
   
        /*
        * public File(String pathname)  把字符串表示的路径变成File对象
        * public File(String parent,String child) 把父级路径和子级路径进行拼接
        * public File(File parent,String child) 把父级路径和子级路径进行拼接
        * windows: "\"
        * java:"\"->转义字符,所以得有两个\\
        * Linux:"/"
        * */


        String str = "C:\\Users\\zhangtenlan\\Desktop\\test.txt";

        //1.public File(String pathname)  把字符串表示的路径变成File对象
        File f1 = new File(str);
        System.out.println(f1);//C:\Users\zhangtenlan\Desktop\test.txt


        //2.public File(String parent,String child) 把父级路径和子级路径进行拼接
        //父级路径:C:\Users\zhangtenlan\Desktop
        //子级路径:test.txt
        String parent = "C:\\Users\\zhangtenlan\\Desktop";
        String child = "test.txt";
        File f2 = new File(parent,child);
        System.out.println(f2);//C:\Users\zhangtenlan\Desktop\test.txt


        //3.public File(File parent,String child) 把父级路径和子级路径进行拼接
        File fparent = new File(parent);
        File f3 = new File(fparent,child);
        System.out.println(f3);//C:\Users\zhangtenlan\Desktop\test.txt
    }
}

2.2File的成员方法(判断,获取)

判断方法演示:

public class Demo2 {
   
    public static void main(String[] args) {
   
        //public boolean isDirectory()  判断此路径名表示的File是否为文件夹
        //public boolean isFile()       判断此路径名表示的File是否为文件
        //public boolean exists()       判断此路径名表示的File是否存在

        //1.对一个存在的文件做判断
        File f1 = new File("C:\\Users\\zhangtenlan\\Desktop\\test.txt");
        System.out.println(f1.isDirectory());//false
        System.out.println(f1.isFile());//true
        System.out.println(f1.exists());//true
        System.out.println("----------------------------------------------------");

        //2.对一个存在的文件夹做判断
        File f2 = new File("C:\\Users\\zhangtenlan\\Desktop\\TEST");
        System.out.println(f2.isDirectory());//true
        System.out.println(f2.isFile());//false
        System.out.println(f2.exists());//true
        System.out.println("----------------------------------------------------");

        //3.对一个不存在的文件做判断
        File f3 = new File("C:\\Users\\zhangtenlan\\Desktop\\aaa");
        System.out.println(f3.isDirectory());//false
        System.out.println(f3.isFile());//false
        System.out.println(f3.exists());//false
    }
}

获取方法演示:

public class Demo3 {
   
    public static void main(String[] args) {
   
        //1.public long length()  返回文件的大小(字节数量Byte)
        File f1 = new File("C:\\Users\\zhangtenlan\\Desktop\\test.txt");
        System.out.println(f1.length());//注意只能获取文件的大小,文件夹却不行

        System.out.println("=================================================");

        //2.public String getAbsolutePath() 返回文件的绝对路径
        File f2 = new File("src/File");//用相对路径创建一个File对象
        System.out.println(f2.getAbsoluteFile());//D:\some_test_project_of_my_own\Day14\src\File

        System.out.println("=================================================");

        //3.public String getPath()   返回定义文件时使用的路径
        System.out.println(f2.getPath());//src\File

        System.out.println("=================================================");

        //4.public String getName()   返回文件名称,带后缀
        System.out.println(f1.getName());//test.txt

        System.out.println("=================================================");

        //5.public long lastModified() 返回文件的最后修改时间(时间毫秒值)
        System.out.println(f1.lastModified());//1738810278724
    }
}

2.3File的成员方法(创建,删除)

public class Demo4 {
   
    public static void main(String[] args) throws IOException {
   
        //1.public boolean createNewFile() 创建一个新的空的文件
        //如果当前路径表示的文件是不存在的,则创建成功,方法返回true
        //如果当前路径表示的文件是存在的,则创建失败,方法返回false
        //如果父级路径是不存在的,那么方法会有异常IOException
        //该方法创建的一定是文件,如果路径中不包含后缀名,则创建一个没有后缀的文件

        File f1 = new File("C:\\Users\\zhangtenlan\\Desktop\\test.txt");
        System.out.println(f1.createNewFile());

        //2.public boolean mkdir() 创建单级文件夹,没什么用,因为它mkdirs既能创建多级又能创建单级


        //3.public boolean mkdirs() 创建多级文件夹
        File f2 = new File("C:\\Users\\zhangtenlan\\Desktop\\aaa\\bbb\\ccc");
        System.out.println(f2.mkdirs());

        //4.public boolean delete() 删除文件,空文件夹
        //如果删除的是文件,则直接删除,不走回收站
        //如果删除的是空文件夹,则直接删除,不走回收站
        //如果删除的是有内容的文件夹,则删除失败
        System.out.println(f1.delete());

    }
}

2.4File的成员方法(获取并遍历)

public class Demo5 {
   
    public static void main(String[] args) {
   
        /*
        * public File[] listFiles() 获取当前该路径下所有内容
        * 当调用者File表示的路径不存在时,返回null
        * 当调用者File表示的路径是文件时,返回null
        * 当调用者File表示的路径是一个空文件夹时,返回一个长度为0的数组
        * 当调用者File表示的路径是一个有内容的文件夹时,将里面所有文件和文件夹的路径放在File数组中返回
        * 当调用者File表示的路径是一个有隐藏文件的文件夹时,将里面所有文件和文件夹的路径放在File数组中返回,包含隐藏文件
        * 当调用者File表示的路径是需要权限才能访问的文件夹时,返回null
        * */
        File f1 = new File("C:\\Users\\zhangtenlan\\Desktop\\aaa");
        File[] arr = f1.listFiles();
        for(File f : arr){
   
            System.out.println(f);
        }

    }
}

内容学习至黑马程序员BV1yW4y1Y7Ms

目录
相关文章
|
机器学习/深度学习 存储 人工智能
完美!京东资深架构师爆肝纯手打700页架构进阶宝典我粉了
在这个大家热议的人工智能时代,也使我们有了更多的反思,其实在这些热点议题的背后,一些基础架构与底层系统技术的发展与实现或许更加务实和接地气一些,同时产业界也需要有更坚实的基础架构与底层系统技术来支撑日益增长的庞大的业务量。 对于支持庞大业务量,其中最具有代表性的莫过于现在的618双十一购物秒杀活动了。而作为参与其中的主力之一的京东,他们的基础架构与底层系统是如何搭建的呢?作为程序猿的我们,该如何脱离CRUD的苦海让自己也加入到这亿级系统的搭建中来呢?不要慌!互联网雷锋(小编我)为大家整理出两份真京东大牛编写的架构实战文档,可以说是国内架构文档的经典之作。
|
1月前
|
存储 Java 程序员
菜鸟之路Day15一一IO流(一)
- **初识IO流**:解释了什么是IO流及其作用,按方向和文件类型分类。 - **字节输出流**:详细讲解了`FileOutputStream`的用法,包括创建对象、写数据和释放资源。 - **字节输入流**:介绍了`FileInputStream`的基本操作,如读取数据和文件拷贝。 - **异常处理**:简要说明了如何处理IO异常。 - **字符集与乱码问题**:解释了字符集的概念及常见乱码原因。 - **字符输入/输出流**:介绍了`FileReader`和`FileWriter`的使用场景和步骤。
31 8
|
21天前
|
存储 数据采集 算法
菜鸟之路Day18一一IO流综合练习
本文通过Java代码实现了一个姓名生成器,从指定网页爬取姓氏、男孩名和女孩名数据,处理后生成随机组合的姓名,并附加性别和年龄信息,最终将结果写入文件。代码涵盖了网页爬虫、正则表达式匹配、随机化处理等技术点。此外,还使用了hutool包简化了部分操作。文章进一步扩展到随机点名器的应用场景,包括简单随机点名、按概率点名、带权重的随机点名等多种变体,满足不同需求的测试场景。
26 2
|
25天前
|
JSON Java 程序员
菜鸟之路Day17一一IO流(三)
本文主要介绍了Java中的打印流、压缩/解压缩流以及Commons-io和Hutool工具包的使用。打印流包括字节打印流(PrintStream)和字符打印流(PrintWriter),支持数据原样写出、自动刷新与换行。压缩/解压缩流通过ZipInputStream和ZipOutputStream实现文件和文件夹的压缩与解压。Commons-io和Hutool工具包提供了高效的IO操作方法,简化了文件复制、删除等常见任务。文中还展示了System.out.println()作为打印流的应用示例。
38 2
|
25天前
|
小程序 Java 程序员
菜鸟之路Day16一一IO流(二)
1. **缓冲流**:介绍了字节缓冲流和字符缓冲流的种类及其性能提升原理,重点讲解了`BufferedReader`和`BufferedWriter`的特有方法。 2. **转换流**:讲解了如何使用`InputStreamReader`和`OutputStreamWriter`实现字符集编码转换,避免乱码问题。 3. **对象序列化与反序列化**:详细说明了如何将Java对象保存到文件中及从文件中读取对象,并讨论了相关细节,如`Serializable`接口、`serialVersionUID`和`transient`关键字的使用。
47 1
|
2月前
|
存储 Java 程序员
菜鸟之路Day13一一方法引用
### 菜鸟之路Day13——方法引用 作者:blue 日期:2025.1.31 本文介绍了Java中的方法引用,它是对Stream流的优化,简化了代码结构。方法引用可以用于静态方法、成员方法和构造方法。通过将已有方法作为函数式接口的实现,减少了匿名内部类和Lambda表达式的冗余。文中通过多个实例演示了方法引用的应用场景,包括倒序排序、字符串转换、集合过滤及对象构造等操作,帮助读者更好地理解和使用这一特性。
60 17
|
9月前
|
存储 索引
技术经验分享:base64详解
技术经验分享:base64详解
42 0
|
SQL Arthas 运维
取经阿里十年技术大佬,得到Java线上问题排查攻略!
再牛逼的程序员都写不出完美无缺的代码,作为后端开发工程师,一不小心就会遇到线上故障。如果线上故障处理不及时,就可能导致各种严重的后果。恰好最近部门出现了一次挺严重但幸运的是影响面不大的线上故障,最后在阿里工作十年的leader分享了线上问题的排查思路。结合这次分享,写下了这篇Java线上问题排查攻略。
|
机器学习/深度学习 人工智能 算法
【架构设计】资深 CIO Neal Sample:所有架构都是错误的
【架构设计】资深 CIO Neal Sample:所有架构都是错误的
|
网络协议 安全 Java
2.图灵学院-----阿里/京东/滴滴/美团整理----高频JAVA网络/IO篇
2.图灵学院-----阿里/京东/滴滴/美团整理----高频JAVA网络/IO篇
124 0
2.图灵学院-----阿里/京东/滴滴/美团整理----高频JAVA网络/IO篇