【JAVA CORE_API】Day17 转换流、缓冲字符流、异常概念try、catch、finally、throw、throws、异常API、自定义异常

news2024/9/22 17:26:09

字符流

字符流

字符流

  • 字符流是以字符(char)为单位读写数据的,一次处理一个unicode
  • java.io.Reader是所有字符输入流的父类;
  • java.io.Writer是所有字符输出流的父类;
  • 字符流仅适合读写文本数据。

字符输入流

  • Reader的常用方法:
    • int read():读取一个字符,返回int值,“低16位”有效;
    • int read(char[] chs):从该流中读取一个字符数组的length个字符并存入该数组,返回值位实际读取到的字符量。
  • Writer的常用方法:
    • void write(int c):写出一个字符,写出给定int值,“低16位”表示的字符;
    • void write(char[] chs):将给定字符数组中所有字符写出;
    • void write(String str):将给定的字符串写出;
    • void write(char[] chs, int offset, int len):将给定的字符数组中从offset处开始连续的len个字符写出。
    • 写出字节数据

  • 文件输出流继承自java.io.OutputStream
  • 文件输出流提供了父类中要求的写出字节的相关方法;
    • void write(int d):写出一个字节。写出的是给定intd对应2进制的“低8位”;
    • void write(byte[] data):块写操作,一次性将给定字节数组data中所有字节写出;
    • void write(byte[] data, int offset, int len):块写操作,一次性将给定字节数组data中从下标offset处连续len个字节写出。

转换流

转换流的意义

  • 字符流只能连接在字符流上使用;
  • 节点流通常都是字节流,在流连接中无法直接将字符流连接在字节流上;
  • 转换流在其中起到“转换器”的作用;
    • 用于衔接字符流与字节流;
    • 对于输出而言:其它字符流泄出的数据经过转换流时会转换为字节再交给字节流写出;
    • 对于输入而言:会从字节流中读取字节并转换为字符后再交给其他字符流进行读取处理;
  • 应用中通常不直接操作转换流。就相当于生活中的:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 字符流不能直接连接在字节流上;

  • 而节点流通常都是字节流;

  • 本质原因是字符流读写字符,字节流读写字节,读写单位不同;

    在这里插入图片描述

  • 转换流本身是字符流,他可以连接在字节流上;

  • 转换流就像转换器一样,可以衔接其它字符流与字节流;

    在这里插入图片描述

  • 转换输出流可以将上层字符流写出的文本数据转换为字节在通过其连接的字节流写出;

    在这里插入图片描述

  • 转换输入流可以从字节流读取相应字节并转换位字符再交给上层字符流做进一步处理;
    在这里插入图片描述

转换流

  • InputStreamReader:转换输入流。
    • 使用该流可以设置字符集,并按照指定的字符集从流中按照该编码将字节数据转换为字符并读取;
  • OutputStreamWriter:转换输出流。
    • 使用该流可以设置字符集,并按照指定的字符集将字符转换为对应字节后通过该流写出;

转换输出流构造器

  • InputStreamReader的构造方法允许我们设置字符集:
    • InputStreamReader(InputStream in, Charset cs):基于给定的字节输入流以及字符编码创建转换输入流;
    • InputStreamReader(InputStream in):该构造方法会根据系统默认字符集创建转换输入流(不推荐使用);

写出文本文本数据

 package day17;
 
 import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.OutputStreamWriter;
 import java.nio.charset.StandardCharsets;
 /**
  * 字符流:java.io.Reader和java.io.Writer
  * 上述两个流是抽象类,是所有字符流的超类,定义了所有字符流都具备的读写字符的操作
  * 字符流都是高级流
  * 转换流:java.io.InputStreamReader和java.io.OutputStreamWriter
  * 转换流是一对常用的字符流的实现类,实际开发中我们不会直接操作转换流,但在流连接中他们非常重要
  *
  * 本案例演示转换流OutputStreamWriter的写出操作----介绍为主
  */
 public class OswDemo {
     public static void main(String[] args) throws IOException {
         FileOutputStream fileOutputStream = new FileOutputStream("osw.txt");
         // 转换流在创建时可以明确字符集,通过它写出的文字都会使用该字符集来转换为字节
         OutputStreamWriter outputStreamWriter = new OutputStreamWriter(fileOutputStream, StandardCharsets.UTF_8);
         // 字符流支持直接写出字符串,转换流会将字符串转换为字节后再通过文件流写出
         outputStreamWriter.write("久未放晴的天空 依旧留着你的笑容");
         outputStreamWriter.write("哭过 却无法掩埋歉疚");
         System.out.println("写出成功");
         outputStreamWriter.close();
     }
 }
 

读取文本数据

 package day17;
 
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.InputStreamReader;
 import java.nio.charset.StandardCharsets;
 /**
  * 演示转换流InputStreamReader的读取操作----介绍为主
  */
 public class IsrDemo {
     public static void main(String[] args) throws IOException {
         FileInputStream fileInputStream = new FileInputStream("osw.txt");
         InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream, StandardCharsets.UTF_8);
         // read() 夫区一个字符,返回值为int类型,这个int类型的“低16位”有效,-1表示读到了文件的末尾
         int d;
         while ((d = inputStreamReader.read()) != -1) {
             System.out.println((char) d);
         }
         inputStreamReader.close();
     }
 }
 

缓冲字符输出流

PrintWriter

  • PrintWriter是具有自动行刷新功能的缓冲字符输出流;
    • 内部总是连接BufferdWriter作为缓冲块写(默认8192长的char数组)文本数据
    • 可以按行写出字符串;
    • 具有自动行刷新功能;

构造器

  • 提供了比较丰富的构造方法:
    • PrintWriter(File file)
    • PrintWriter(String fileName)
    • PrintWriter(OutputStream out)
    • PrintWriter(OutputStream out, boolean autoFlush)
    • PrintWriter(Writer writer)
    • PrintWriter(Writer writer, boolean autoFlush)
  • 基于参数OutputStreamWriter的构造方法提供了一个可以传入boolean值参数,该参数用于表示PrintWriter是否具有自动行刷新。

PrintWriter

  • PrintWriter提供了丰富的重载printprintln方法。
  • 常用方法:
    • void print(int i):打印整数;
    • void print(char c):打印字符;
    • void print(boolean b):打印boolean值;
    • void print(char[] c):打印字符数组;
    • void print(double d):打印double值;
    • void print(float f):打印float值;
    • void print(long l):打印long值;
    • void print(String str):打印字符串;
  • 上述方法都有println方法。

简易记事本v2.0

  • 输入数据:

     package day17;
     
     import java.io.*;
     import java.nio.charset.StandardCharsets;
     import java.util.Scanner;
     
     /**
      * 完成简易记事本升级版:
      * 需求:程序启动后将用户输入的每一行字符串都按行写入到note.txt中,用户输入exit输出
      * 要求:完成四层流连接
      */
     public class NoteTestV2 {
         public static void main(String[] args) throws FileNotFoundException {
             // 创建一个扫描仪
             Scanner scanner = new Scanner(System.in);
             // 四层流连接 --- 创建一个文件输出流对象
             FileOutputStream fileOutputStream = new FileOutputStream("note.txt");
             // 四层流连接 --- 创建一个转换流对象
             OutputStreamWriter outputStreamWriter = new OutputStreamWriter(fileOutputStream, StandardCharsets.UTF_8);
             // 四层流连接 --- 创建一个缓冲流对象
             BufferedWriter bufferedWriter = new BufferedWriter(outputStreamWriter);
             // 四层流连接 --- 创建一个打印流对象
             PrintWriter printWriter = new PrintWriter(bufferedWriter, true);
     
             System.out.println("请输入内容:");
             while (true) {
                 String string = scanner.nextLine();
                 if ("exit".equalsIgnoreCase(string)) {  // 判断用户输入的字符串是否为exit
                     break;
                 } else {
                     printWriter.println(string);
                 }
             }
             System.out.println("记录完成!再见!");
             printWriter.close();
     
         }
     }
     
    
  • 输出数据:

     package day17;
     
     import java.io.*;
     import java.nio.charset.StandardCharsets;
     
     /**
      * 使用缓冲字符输入流BufferedReader按行读取字符串:
      * 1) 内部维护一个8192字节长的char数组,可以块读文本数据保证读取效率;
      * 2) 提供了readLine()方法可以按行读取字符串;
      */
     public class BrDemo {
         public static void main(String[] args) throws IOException {
             FileInputStream fileInputStream = new FileInputStream("note02.txt");
             InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream, StandardCharsets.UTF_8);
             BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
     
             /**
              * readLine()方法读取一行字符串
              * 1) 读到\n换行符,返回一行字符串;
              * 2) 读到空行,则返回空字符串
              * 3) 读到了末尾,则返回null
              */
             String line;
             while ((line = bufferedReader.readLine()) != null) {
                 System.out.println(line);
             }
             bufferedReader.close();
         }
     }
     
    

缓冲字符输入流

BufferedReader

  • BufferedReader是缓冲字符输入流;
    • 内部维护一个char数组作为缓冲区(默认8192字节长)缓存文本数据,以块读形式保证读取效率;
    • 可以按行读取字符串;

构造器

  • BufferedReader(Reader reader):创建默认8192字节长缓冲区的缓冲字符输入流并连接在参数指定的流上;
  • BufferedReader(Reader reader, int sz):创建sz指定长度缓冲区的缓冲字符输入流并连接在参数指定的流上。

按行读取字符串

  • BufferedReader提供了一个可以便于读取一行字符串的方法:
    • String readLine():该方法返回缓冲区中一行字符串,返回的字符串中不包含该换行符。当返回值为null时,表示流读取到了末尾。

异常处理机制

异常处理概述

使用返回值状态标识异常

  • 在Java语言出现以前,传统的异常处理方式多采用返回值来标识处现的异常情况,这种方式虽然为程序员所熟悉,但却有很多坏处;
  • 首先,一个API可以返回任意的返回值,而这些返回值本身并不能解释该返回值是否代表一个异常情况发生了和该异常的具体情况,需要调用API的程序自己判断并解释返回值的含义;
  • 其次,并没有一种机制来保证异常情况一定会得到处理,调用程序可以简单地忽略该返回值,需要调用API的程序员记住去检测返回值并处理异常情况。这种方式还让程序代码变得冗长,尤其是当进行IO操作等容易出现异常情况的处理时,代码的很大部分用于处理异常情况的switch分支,程序代码的可读性变得很差。

异常处理机制

  • 当程序中抛出一个异常后,程序从程序中导致异常的代码处跳出,Java虚拟机检测寻找和try关键字匹配处理该异常的catch块,如果找到,将控制权交到catch块中的代码,然后继续往下执行该程序,try块中发生异常的代码不会被重新执行。如果没有找到处理该异常的catch块,在所有的finally块代码被执行和当前线程的所属的ThreadGroupuncaughtException方法被调用后,遇到异常的当前线程被终止。

异常的分类

Throwable, Error和Exception

  • Java异常结构中定义有Throwable类,ExceptionError是其派生的两个子类。其中Exception表示由于网络故障、文件损坏、设备错误、用户输入非法等情况导致的异常;而Error表示Java运行时环境出现的错误,例如:JVM内存资源耗尽等。
    在这里插入图片描述

try-catch

try-catch

  • try{ ... } 语句指定了一段代码,这段代码就是一次捕获并处理例外的范围;
  • 在执行过程中,该段代码可能会产生并抛出一种或几种类型的异常对象,它后面的catch语句分别对这些异常做相应的处理;
  • 如果没有异常产生,所有的catch代码段都被略过不执行;
  • catch语句块中是对异常进行处理的代码;
  • catch中生命的异常对象(catch(SomeException e))封装了异常事件发生的信息,在catch语句块中可以使用这个对象的一些方法获取这些信息。
  • 语法格式:
     try {
         正常的代码片段(Plan A} catch (XXXException) {try中的代码出现了XXXException异常之后的处理代码(Plan B}
    
  • try-catch示例:
     package day17;
     
     public class TryCatchDemo {
         public static void main(String[] args) {
             try {
                 String string = null;
                 System.out.println(string.length());
             } catch (NullPointerException e) {
                 System.out.println("空指针异常");
             }
         }
     }
     
    
  • 多catch示例:
     package day17;
     
     public class TryCatchDemo {
         public static void main(String[] args) {
             try {
             //  String string = null;
             //  System.out.println(string.length());  // 会走空指针异常
                 String string1 = "abc";
                 System.out.println(string1.charAt(5));  // 会走字符串索引越界异常
             } catch (NullPointerException e) {
                 System.out.println("空指针异常");
             } catch (StringIndexOutOfBoundsException e) {
                 System.out.println("字符串索引越界异常");
             }
         }
     }
     
    
  • 合并catch示例:
     package day17;
     
     public class TryCatchDemo {
         public static void main(String[] args) {
             try {
             //  String string = null;
             //  System.out.println(string.length());  // 会走空指针异常
                 String string1 = "abc";
                 System.out.println(string1.charAt(5));  // 会走字符串索引越界异常
             } catch (NullPointerException | StringIndexOutOfBoundsException e) {
                 System.out.println("空指针异常或字符串索引越界异常");
             }
         }
     }
     
    
  • 全报示例:
     package day17;
     
     public class TryCatchDemo {
         public static void main(String[] args) {
             try{
                 String string = "abc";
                 System.out.println(Integer.parseInt(string));
             } catch(Exception e) {  // 这是所有异常的父类,也叫超类型异常
                 System.out.println("不知道,反正出了个错!");
             }
         }
     }
     
    
  • 注意:
    • try中的代码不出现异常时,catch语句是不执行的;
    • try语句块中某语句发生异常后,剩余代码不会被执行;
    • catch可以定义多个,针对不同的一场有不同的处理方式以分别捕获处理;
    • 当多个异常具有相同的处理方式时,可以合并到一个catch中处理;
    • 捕获超类型(Exception e)异常,那么它的所有子类型异常都可以被处理;
    • 如果catch的一场存在继承关系,那么子类异常在上,父异常在下。

finally

finally块

  • finally语句为异常处理提供一个统一的出口,使得在控制流程转到其他程序部分以前,能够对程序的状态同统一地管理;
  • 无论try所制定的程序块中是否抛出异常,finally所制定的代码都要被执行;
  • 通常在finally语句中可以进行资源的释放工具,如果关闭打开文件、删除临时文件等;
     package day17;
     
     public class FinallyDemo {
         public static void main(String[] args) {
             System.out.println("程序01开始了...");
     
             // 没有异常也会走finally
             try{
                 String string = "abc";
                 System.out.println(string.length());
             } catch (Exception exception) {
                 System.out.println("不知道,反正出了个错!");
             } finally {
                 System.out.println("程序01里面的finally执行了!");
             }
             System.out.println("程序01结束了...");
     
             System.out.println("----------------------------");
     
             // 有异常也会走finally
             try{
                 String string = null;
                 System.out.println(string.length());
             } catch (Exception exception) {
                 System.out.println("不知道,反正出了个错!");
             } finally {
                 System.out.println("程序02里面的finally执行了!");
             }
             System.out.println("程序02结束了...");
     
             System.out.println("---------------------------------");
     
             // 哪怕return也走
             try{
                 String string = null;
                 System.out.println(string.length());
                 return;
             } catch (Exception exception) {
                 System.out.println("不知道,反正出了个错!");
             } finally {
                 System.out.println("程序03里面的finally执行了!");
             }
             System.out.println("程序03结束了...");
         }
     }
     
    

异常处理在IO中的应用

 package day17;
 
 import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
 import java.io.IOException;
 
 /**
  * 异常处理机制在IO中的应用
  */
 public class FinallyIODemo {
     public static void main(String[] args) {
         FileOutputStream fileOutputStream = null;
         // ctrl+alt+t 快速生成 try catch
         try {
             fileOutputStream = new FileOutputStream("fos.dat");
             fileOutputStream.write(1);
         } catch (IOException e) {
             System.out.println("出现异常了!");;
         } finally {
             try {
                 if (fileOutputStream != null) {
                     fileOutputStream.close();
                     System.out.println("完成!");
                 }
             } catch (IOException e) {
                 System.out.println("关闭资源出现异常了!");;
             }
         }
 
     }
 }
 

异常处理机制

自动关闭特性

自动关闭特性

  • JDK7之后,Java推出了自动关闭特性;
  • 旨在更优雅的在异常处理机制中关闭,如:流这样的操作。
     package day17;
     
     import java.io.FileNotFoundException;
     import java.io.FileOutputStream;
     import java.io.IOException;
     
     /**
      * JDK7之后,Java推出了一个新特性,自动关闭特性.
      * 可以使我们在异常处理机制中更优雅的关闭如“流”这样的资源
      */
     public class AutoCloseableDemo {
         public static void main(String[] args) {
             /**
              * 只要实现了AutoCloseable接口的类,才可以在try()中定义
              * 所有流都实现了该接口,意味着可以将流定义并初始化在try()中,会自动进行流的关闭。
              */
             try (FileOutputStream fileOutputStream = new FileOutputStream("fos.dat")) {
                 fileOutputStream.write(1);
             } catch (IOException e) {
                 System.out.println("出现异常了!");;
             }  // 无需写finally了
         }
     }
     
    

异常的抛出

throw关键字

  • 当程序发生错误而无法处理的时候后,会抛出对应的异常对象,除此之外,在某些时刻,我们可能会想要自行抛出异常,例如在异常处理结束后,再将异常抛出,让下一层异常处理块来捕捉,若想要自行抛出异常,我们可以使用throw关键字,并声称指定的异常对象后抛出。
  • 例如:
    throw new ArithmeticException();
  • 示例代码:
    • Person类:
     package day17;
     
     import java.util.Objects;
     
     public class Person {
         private String name;
         private int age;
         private String gender;
         private String address;
     
         public Person() {
         }
     
         public Person(String name, int age, String gender, String address) {
             this.name = name;
             this.age = age;
             this.gender = gender;
             this.address = address;
         }
     
         public String getName() {
             return name;
         }
     
         public void setName(String name) {
             this.name = name;
         }
     
         public int getAge() {
             return age;
         }
     
         public void setAge(int age) {
             if (age < 0 || age > 200) {
                 throw new RuntimeException("年龄不合法,正确的年龄应在0到200之间!");
             }
             this.age = age;
         }
     
         public String getGender() {
             return gender;
         }
     
         public void setGender(String gender) {
             this.gender = gender;
         }
     
         public String getAddress() {
             return address;
         }
     
         public void setAddress(String address) {
             this.address = address;
         }
     
         @Override
         public boolean equals(Object o) {
             if (this == o) return true;
             if (o == null || getClass() != o.getClass()) return false;
             Person person = (Person) o;
             return age == person.age && Objects.equals(name, person.name) && Objects.equals(gender, person.gender) && Objects.equals(address, person.address);
         }
     
         @Override
         public int hashCode() {
             return Objects.hash(name, age, gender, address);
         }
     
         @Override
         public String toString() {
             return "Person{" +
                     "name='" + name + '\'' +
                     ", age=" + age +
                     ", gender='" + gender + '\'' +
                     ", address='" + address + '\'' +
                     '}';
         }
     
     }
     
    
    • 测试类:
     package day17;
     
     /**
      * throw关键字,用于将一个异常抛出。
      * 通常下列情况下会将一个异常抛出方法外:
      * 1)当前代码片段出现了异常,但是该异常不应该在此处被处理(不是我们的责任);
      * 2)程序可以运行,但运行结果不符合实际业务需求(本案例演示)
      */
     public class ThrowDemo {
         public static void main(String[] args) {
             Person person = new Person("张禹垚", 18, "男", "南京");
             person.setAge(2000);
             System.out.println("此人年龄:" + person.getAge());
         }
     }
     
    
    如果这时我们输入非法的数据,会出现:
    在这里插入图片描述

throws关键字

  • 程序中会生命许多方法(Method),这些方法中可能会因某些错误而引发异常,但如果我们不希望直接在这个方法中处理这些异常,而希望调用这个它的方法来统一处理,这时候我们可以使用“throws”关键字来声明这个方法将会抛出异常。
  • 除了RunTimeException以外,当主动使用throw抛出异常时,编译器要求必须在方法中使用throws来声明异常的抛出,以便通知调用者处理。
     package day17;
     
     import java.util.Objects;
     
     public class Person {
         private String name;
         private int age;
         private String gender;
         private String address;
     
         public Person() {
         }
     
         public Person(String name, int age, String gender, String address) {
             this.name = name;
             this.age = age;
             this.gender = gender;
             this.address = address;
         }
     
         public String getName() {
             return name;
         }
     
         public void setName(String name) {
             this.name = name;
         }
     
         public int getAge() {
             return age;
         }
     
         public void setAge(int age) throws Exception{
             if (age < 0 || age > 200) {
                 throw new Exception("年龄不合法,正确的年龄应在0到200之间!");
             }
             this.age = age;
         }
     
         public String getGender() {
             return gender;
         }
     
         public void setGender(String gender) {
             this.gender = gender;
         }
     
         public String getAddress() {
             return address;
         }
     
         public void setAddress(String address) {
             this.address = address;
         }
     
         @Override
         public boolean equals(Object o) {
             if (this == o) return true;
             if (o == null || getClass() != o.getClass()) return false;
             Person person = (Person) o;
             return age == person.age && Objects.equals(name, person.name) && Objects.equals(gender, person.gender) && Objects.equals(address, person.address);
         }
     
         @Override
         public int hashCode() {
             return Objects.hash(name, age, gender, address);
         }
     
         @Override
         public String toString() {
             return "Person{" +
                     "name='" + name + '\'' +
                     ", age=" + age +
                     ", gender='" + gender + '\'' +
                     ", address='" + address + '\'' +
                     '}';
         }
     
     }
     
    
  • 当我们调用一个含有throws声明异常抛出的方法时,编译器要求我们必须处理该异常,方法如下:
    • 使用try...catch...处理该异常;
    • 在当前方法上继续使用throws对该异常抛出;
    • 注意:具体选择哪种方式,取决于责任问题;
    • 记住:永远不要再main方法上写throws,否则直接杀死主方法。

重写方法时的throws

  • 如果使用继承时,在父类的某个方法上宣告了throws某些异常,而在子类里重新定义该方法时,我们可以:
    • 不处理异常(重新定义时不设定throws);
    • 可仅throws父类中声明的部分异常;
    • throws父类方法中抛出异常的子类异常;
      但不可以:
    • throws出额外的异常;
    • throws父类方法中抛出异常的父类异常。
     package day17;
     
     import java.awt.*;
     import java.io.FileNotFoundException;
     import java.io.IOException;
     import java.sql.SQLException;
     
     /**
      * 子类重写父类含有throws声明异常抛出的方法时,对throws的重写规则
      */
     public class ThrowsDemo {
         public void doSome() throws IOException, AWTException {
             
         }
     }
     
     class SubClass extends ThrowsDemo {
      // public void doSome() throws IOException {}  // 允许仅抛出部分异常
      // public void doSome() throws IOException, AWTException {}  // 允许全部抛出
      // public void doSome() {}  // 允许不抛出异常
      // public void doSome() throws FileNotFoundException {} // 允许抛出异常类型小于父类的方法
         
      // public void doSome() throws SQLException {}  // 不允许抛出额外异常(父类中没有继承关系的异常)
      // public void doSome() throws Exception{}  // 不允许抛出大于父类方法的异常   
         
     }
    

Java异常常见API

检查异常与非检查异常

  • Java异常可以分为可检测异常与非检测异常:
    • 可检测异常:可检测异常经编译器验证,对于声明抛出异常的任何方法,编译器将强制执行处理或声明规则,不捕捉这个异常,编译器就通不过,不允许编译;
    • 非检测异常:非检测异常不遵循处理或声明规则。在产生此类异常时,不一定非要采取任何适当操作,编译器不会检查是否已经解决了这个异常;
  • RuntimeException类属于非检测异常,因为普通JVM操作引起的运行时异常随时可能发生,此类异常一般是由特定操作引发。但这些操作在Java应用程序中会频繁出现。因此他们不受编译器检查预处理或声明规则的限制;

常见RuntimeException

  • IllegalArgumentException:抛出的异常表明像方法传递了一个不合法或不正确的参数;
  • NullPointerException:当应用程序试图在需要对象的地方使用null时,抛出该异常;
  • ArrayIndexOutOfBoundsException:当时用的数组下标超出数组允许范围时,抛出该异常;
  • ClassCastException:当试图将对象强制转换为不是实例的子类时,抛出该异常;
  • NumberFormatException:当应用程序试图将字符串转换成一种数值类型,但该字符串不能转换为适当格式时,抛出该异常。

printStackTrace

  • Throwable中定义了一个方法可以输出错误信息,用来跟踪异常事件发生时执行堆栈的内容。该方法定义为:
    • void printStackTrace()
       try {
         ...
       } catch (Exception e) {
         e.printStackTrace();  // 输出执行堆栈信息
       } 
      

getMessage

  • Throwable中定义了一个方法可以得到有关异常事件的信息。该方法定义为:
    • String getMessage()
      try {
        ...
      } catch (Exception e) {
        System.out.println(e.getMessage);
      } 
      
     package day17;
     
     /**
      * throw关键字,用于将一个异常抛出。
      * 通常下列情况下会将一个异常抛出方法外:
      * 1)当前代码片段出现了异常,但是该异常不应该在此处被处理(不是我们的责任);
      * 2)程序可以运行,但运行结果不符合实际业务需求(本案例演示)
      */
     public class ThrowDemo {
         public static void main(String[] args) {
             Person person = new Person("张禹垚", 21, "男", "黑龙江");
             try {
                 person.setAge(2000);
             } catch (Exception e) {
                 System.out.println(e.getMessage());
             }
             System.out.println("此人年龄:" + person.getAge());
         }
     }
     
    

自定义Exception

自定义异常的意义

  • Java异常机制可以保证程序更安全和更健壮。虽然Java类库已经提供很多可以直接处理异常的类,但是有时候为了更加精准地捕获和处理异常以呈现更好的用户体验,需要开发者自定义异常。
  • 自定义变量要完成下列操作:
    • 类名要做到见名知意;
    • 必须继承自Exception(直接或间接);
    • 提供从父类异常定义的所有构造器。
     package day17;
     
     /**
      * 非法年龄异常
      * 通常在项目中需要描述一个语法正确,但是不符合业务需求的需求时,可以自定义异常
      * 自定义异常应当满足如下要求:
      * 1)类名应当见名知意;
      * 2)自定义异常的类一定要继承自Exception类或Runtime类;
      * 3)要添加异常的所有构造器
      */
     public class IllegalAgeException extends Exception {
         public IllegalAgeException() {
         }
     
         public IllegalAgeException(String message) {
             super(message);
         }
     
         public IllegalAgeException(String message, Throwable cause) {
             super(message, cause);
         }
     
         public IllegalAgeException(Throwable cause) {
             super(cause);
         }
     
         public IllegalAgeException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
             super(message, cause, enableSuppression, writableStackTrace);
         }
     }
     
    
     package day17;
     
     import java.util.Objects;
     
     public class Person {
         private String name;
         private int age;
         private String gender;
         private String address;
     
         public Person() {
         }
     
         public Person(String name, int age, String gender, String address) {
             this.name = name;
             this.age = age;
             this.gender = gender;
             this.address = address;
         }
     
         public String getName() {
             return name;
         }
     
         public void setName(String name) {
             this.name = name;
         }
     
         public int getAge() {
             return age;
         }
     
         public void setAge(int age) throws IllegalAgeException{
             if (age < 0 || age > 200) {
                 throw new IllegalAgeException("年龄不合法,正确的年龄应在0到200之间!");
             }
             this.age = age;
         }
     
         public String getGender() {
             return gender;
         }
     
         public void setGender(String gender) {
             this.gender = gender;
         }
     
         public String getAddress() {
             return address;
         }
     
         public void setAddress(String address) {
             this.address = address;
         }
     
         @Override
         public boolean equals(Object o) {
             if (this == o) return true;
             if (o == null || getClass() != o.getClass()) return false;
             Person person = (Person) o;
             return age == person.age && Objects.equals(name, person.name) && Objects.equals(gender, person.gender) && Objects.equals(address, person.address);
         }
     
         @Override
         public int hashCode() {
             return Objects.hash(name, age, gender, address);
         }
     
         @Override
         public String toString() {
             return "Person{" +
                     "name='" + name + '\'' +
                     ", age=" + age +
                     ", gender='" + gender + '\'' +
                     ", address='" + address + '\'' +
                     '}';
         }
     
     }
     
    
     package day17;
     
     /**
      * throw关键字,用于将一个异常抛出。
      * 通常下列情况下会将一个异常抛出方法外:
      * 1)当前代码片段出现了异常,但是该异常不应该在此处被处理(不是我们的责任);
      * 2)程序可以运行,但运行结果不符合实际业务需求(本案例演示)
      */
     public class ThrowDemo {
         public static void main(String[] args) {
             Person person = new Person("张禹垚", 21, "男", "黑龙江");
             try {
                 person.setAge(2000);
             } catch (IllegalAgeException e) {
                 System.out.println(e.getMessage());
             }
             System.out.println("此人年龄:" + person.getAge());
         }
     }
     
    

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2054283.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

计算机毕业设计选题推荐-springboot 基于springboot的扶贫助农系统

✍✍计算机编程指导师 ⭐⭐个人介绍&#xff1a;自己非常喜欢研究技术问题&#xff01;专业做Java、Python、微信小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目&#xff1a;有源码或者技术上的问题欢迎在评论区一起讨论交流&#xff01; ⚡⚡ Java实战 |…

vscode中自定义vue模板(生成的模版里边的div是自己建的文件名)

1.点击之后会出来这个页面 点击去 然后输入下边这段json就可以了 {"vue3模板": {"prefix": "vue","description": "vue3模板","body": ["<template>","<div class$TM_FILENAME_BASE&g…

网络编程/在哪些场景中不必要进行网络字节序转换? Windows Sockets: Byte Ordering

文章目录 概述字节序必须转换字节序的的情况不必转换字节序的的情况字节序转换的例程字节序转换函数字节序转换可以不生硬字节序和位序 概述 本文主要讲述了在哪些场景下必须要进行大小端字节序转换&#xff0c;在哪些场景下可以不用进行大小端字节序转换&#xff0c;IP和端口…

并查集+思维,CF 1039C - Network Safety

目录 一、题目 1、题目描述 2、输入输出 2.1输入 2.2输出 3、原题链接 二、解题报告 1、思路分析 2、复杂度 3、代码详解 一、题目 1、题目描述 2、输入输出 2.1输入 2.2输出 3、原题链接 1039C - Network Safety 二、解题报告 1、思路分析 考虑边<u, v>&…

深度学习基础—动量梯度下降法

1.算法原理 动量梯度下降法就是在梯度下降法的基础上&#xff0c;使用指数加权移动平均值&#xff0c;来平均梯度&#xff0c;这种算法比梯度下降法更快。 如上图&#xff0c;损失函数的最小值是红点&#xff0c;椭圆是损失函数的图像&#xff0c;梯度下降法就像蓝线和紫线&…

Linux安装MQTT 服务器(图文教程)

MQTT&#xff08;Message Queuing Telemetry Transport&#xff09;是一种轻量级的消息传输协议&#xff0c;专为低带宽和不稳定的网络环境设计&#xff0c;非常适合物联网&#xff08;IoT&#xff09;应用。 官网地址&#xff1a;https://www.emqx.com/ 一、版本选择 根据自己…

el-tree多选的父子关联和父子不关联和拖拽功能

公用js变量&#xff1a; data () {return {// 绑定的数组treeData: [],// 多选选择的idids: []} }, 公用js方法&#xff1a; /*** 选择多选改变*/ nodeChange(data, checked, indeterminate) {let keys this.$refs.treeCategory.getCheckedKeys();this.ids keys; } 第一种…

Android 架构模式之 MVP

目录 架构设计的目的对 MVP 的理解代码ModelViewPresenter Android 中 MVP 的问题试吃个小李子ModelViewPresenter 大家好&#xff01; 作为 Android 程序猿&#xff0c;你有研究过 MVP 架构吗&#xff1f;在开始接触 Android 那一刻起&#xff0c;我们就开始接触 MVC 架构&am…

“解决Windows电脑无法投影到其他屏幕的问题:尝试更新驱动程序或更换视频卡“

背景: 今天在日常的工作中&#xff0c; 我想将笔记本分屏到另一个显示屏&#xff0c;我这电脑Windows10&#xff0c;当我按下Windows键P键&#xff0c;提示我"你的电脑不能投影到其他屏幕&#xff0c;请尝试从新安装驱动程序或使用"遇到这种问题。 解决方法1: 1.快…

解决 idea 创建maven项目卡住

一, 现象 选择一个Archetype后创建项目,一直卡着,点哪里都点不了,有的博客说可以看maven的日志排查问题,我这里没有任何日志输出 二,为什么会卡住 结论: 因为idea在从中央仓库下载archetype-catalog.xml(文件较大,14.8M)导致卡住 分析: 首先要明白通过Archetype创建…

openssl查看证书公钥 openssl 验证证书和密钥

例如&#xff1a;中间件或者openssl生成国密证书请求文件文件里面省份必须写陕西省三个汉字 安装完成后&#xff0c;使用下列命令查看该版本的openssl是否支持SM2参数&#xff1a; openssl ecparam -list_curves | grep SM2 查看openssl版本信息 openssl version -a 查看open…

【C++篇】迈入新世界的大门——初识C++(下篇)

文章目录 前言引用引用的概念和定义引用的特性引用的使用const引用指针和引用的关系 inline#define定义宏inline nullptr 前言 接上篇&#xff1a;【C篇】迈入新世界的大门——初识C&#xff08;上篇&#xff09; 引用 引用的概念和定义 引⽤不是新定义⼀个变量&#xff0c;…

第10章 无持久存储的文件系统 (3)

目录 10.2 简单文件系统 10.2.1 顺序文件 10.2.2 用libfs编写文件系统 10.2.3 调试文件系统 10.2.4 伪文件系统 10.3 sysfs 10.3.1 概述 10.3.2 数据结构 10.3.3 装载文件系统 10.3.4 文件和目录操作 10.3.5 向sysfs添加内容 10.4 小结 本专栏文章将有70篇左右&…

Node.js及mysql的安装,建立页面,javascript对mySQL数据库的操作过程

具体动态效果看视频 node.js连接MySQL数据库操作 第一部分&#xff1b;配置服务器环境 Nods.js, NPM,CNPM,mysql2,express的安装 前往 Node.js 官方网站&#xff08;https://nodejs.org/&#xff09;下载并安装最新的稳定版本&#xff0c;确定配置好path环境变量&#xff0c;其…

Linux网络环境搭建,开发板网线直连电脑网口,电脑WIFI上网

开发板网线直连电脑网口&#xff08;电脑自带&#xff0c;一般有PCI&#xff0c;不是USB网卡&#xff09;&#xff0c;电脑WIFI上网 因为电脑是 WiFi 上网&#xff0c;所以需要添加一个网络适配器并设置成 NAT 模式&#xff0c;供虚拟机上网。 设置双网卡&#xff0c;注意双网卡…

SQL 时间盲注 (injection 第十五关)

简介 SQL注入&#xff08;SQL Injection&#xff09;是一种常见的网络攻击方式&#xff0c;通过向SQL查询中插入恶意的SQL代码&#xff0c;攻击者可以操控数据库&#xff0c;SQL注入是一种代码注入攻击&#xff0c;其中攻击者将恶意的SQL代码插入到应用程序的输入字段中&#x…

visual studio使用技巧:快速生成Json、XML对应类

visual studio快速生成Json、XML对应类 在项目中经常用到json或者xml作为配置文件&#xff0c;进行序列化和反序列化就需要有对应的类&#xff0c;重新写一遍类就比较麻烦&#xff0c;这里就讲一下通过visual studio快速生成json或者xml对应类型的方法。 自动生成Json类 复制…

大数据-90 Spark 集群 RDD 编程-高阶 RDD容错机制、RDD的分区、自定义分区器(Scala编写)、RDD创建方式

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; 目前已经更新到了&#xff1a; Hadoop&#xff08;已更完&#xff09;HDFS&#xff08;已更完&#xff09;MapReduce&#xff08;已更完&am…

【Python】AttributeError: module ‘PIL.Image‘ has no attribute ‘ANTIALIAS‘

【Python】成功解决AttributeError: module ‘PIL.Image‘ has no attribute ‘ANTIALIAS‘ 下滑即可查看博客内容 &#x1f308; 欢迎莅临我的个人主页 &#x1f448;这里是我静心耕耘深度学习领域、真诚分享知识与智慧的小天地&#xff01;&#x1f387; &#x1f393; 博…

MySQL集群+Keepalived实现高可用部署

Mysql高可用集群-双主双活-myqlkeeplived 一、特殊情况 常见案例&#xff1a;当生产环境中&#xff0c;当应用服务使用了mysql-1连接信息&#xff0c;在升级打包过程中或者有高频的数据持续写入【对数据一致性要求比较高的场景】&#xff0c;这种情况下&#xff0c;数据库连接…