加载中...
avatar
文章
42
标签
25
分类
21
首页
Java
Spring全家桶
  • Spring
  • SpringBoot
  • SpringCloud
JVM
源码
  • Mybatis
  • HashMap
归档
其他
  • 互联网电子书汇总
  • JAVA八股文指南
  • 历史
  • 相册
关于
Logo码农StormlingJava系列(四)| 异常处理及IO
搜索
首页
Java
Spring全家桶
  • Spring
  • SpringBoot
  • SpringCloud
JVM
源码
  • Mybatis
  • HashMap
归档
其他
  • 互联网电子书汇总
  • JAVA八股文指南
  • 历史
  • 相册
关于

Java系列(四)| 异常处理及IO

发表于2021-09-19|更新于2025-01-07|Java
|总字数:1.6k|阅读时长:5分钟|浏览量:

Java 中异常处理体系?

Java 的异常体系是分为多层的。

Java 异常体系

Throwable是 Java 语言中所有错误或异常的基类。

Throwable

  • Error:系统内部错误比如虚拟机异常,是程序无法处理的。
  • Exception:程序问题导致的异常
  • CheckedException 受检异常:编译器会强制检查并要求处理的异常。
  • RuntimeException 运行时异常:程序运行中出现异常,比如我们熟悉的空指针、数组下标越界等等

异常的处理方式?

针对异常的处理主要有两种方式:

  • 遇到异常不进行具体处理,而是继续抛给调用者 (throw,throws)

抛出异常有三种形式,一是 throw, 一个 throws,还有一种系统自动抛异常。

throws 用在方法上,后面跟的是异常类,可以跟多个;而 throw 用在方法内,后面跟的是异常对象。

  • try catch 捕获异常

在 catch 语句块中补货发生的异常,并进行处理。

try {
    //包含可能会出现异常的代码以及声明异常的方法
}catch(Exception e) {
    //捕获异常并进行处理
}finally {                                                       }
//可选,必执行的代码
}

try-catch 捕获异常的时候还可以选择加上 finally 语句块,finally 语句块不管程序是否正常执行,最终它都会必然执行。

三道经典异常处理代码题

题目 1

public class TryDemo {
    public static void main(String[] args) {
        System.out.println(test());
    }
    public static int test() {
        try {
            return 1;
        } catch (Exception e) {
            return 2;
        } finally {
            System.out.print("3");
        }
    }
}

执行结果:31。

try、catch。finally 的基础用法,在 return 前会先执行 finally 语句块,所以是先输出 finally 里的 3,再输出 return 的 1。

题目 2

public class TryDemo {
    public static void main(String[] args) {
        System.out.println(test1());
    }
    public static int test1() {
        try {
            return 2;
        } finally {
            return 3;
        }
    }
}

执行结果:3。

try 返回前先执行 finally,结果 finally 里不按套路出牌,直接 return 了,自然也就走不到 try 里面的 return 了。

finally 里面使用 return 仅存在于面试题中,实际开发这么写要挨吊的。

题目 3

public class TryDemo {
    public static void main(String[] args) {
        System.out.println(test1());
    }
    public static int test1() {
        int i = 0;
        try {
            i = 2;
            return i;
        } finally {
            i = 3;
        }
    }
}

执行结果:2。

大家可能会以为结果应该是 3,因为在 return 前会执行 finally,而 i 在 finally 中被修改为 3 了,那最终返回 i 不是应该为 3 吗?

但其实,在执行 finally 之前,JVM 会先将 i 的结果暂存起来,然后 finally 执行完毕后,会返回之前暂存的结果,而不是返回 i,所以即使 i 已经被修改为 3,最终返回的还是之前暂存起来的结果 2。

I/O

Java 中 IO 流分为几种?

流按照不同的特点,有很多种划分方式。

  • 按照流的流向分,可以分为输入流和输出流;
  • 按照操作单元划分,可以划分为字节流和字符流;
  • 按照流的角色划分为节点流和处理流

Java Io 流共涉及 40 多个类,看上去杂乱,其实都存在一定的关联, Java I0 流的 40 多个类都是从如下 4 个抽象类基类中派生出来的。

  • InputStream/Reader: 所有的输入流的基类,前者是字节输入流,后者是字符输入流。
  • OutputStream/Writer: 所有输出流的基类,前者是字节输出流,后者是字符输出流。

IO 流用到了什么设计模式?

其实,Java 的 IO 流体系还用到了一个设计模式——装饰器模式。

InputStream 相关的部分类图如下,篇幅有限,装饰器模式就不展开说了。

既然有了字节流, 为什么还要有字符流?

其实字符流是由 Java 虚拟机将字节转换得到的,问题就出在这个过程还比较耗时,并且,如果我们不知道编码类型就很容易出现乱码问题。

所以, I/O 流就干脆提供了一个直接操作字符的接口,方便我们平时对字符进行流操作。如果音频文件、图片等媒体文件用字节流比较好,如果涉及到字符的话使用字符流比较好。

BIO、NIO、AIO?

BIO、NIO、AIO

BIO(blocking I/O) :就是传统的 IO,同步阻塞,服务器实现模式为一个连接一个线程,即客户端有连接请求时服务器端就需要启动一个线程进行处理,如果这个连接不做任何事情会造成不必要的线程开销,可以通过连接池机制改善 (实现多个客户连接服务器)。

BIO 方式适用于连接数目比较小且固定的架构,这种方式对服务器资源要求比较高,并发局限于应用中,JDK1.4 以前的唯一选择,程序简单易理解。

NIO :全称 java non-blocking IO,是指 JDK 提供的新 API。从 JDK1.4 开始,Java 提供了一系列改进的输入 / 输出的新特性,被统称为 NIO(即 New IO)。

NIO 是同步非阻塞的,服务器端用一个线程处理多个连接,客户端发送的连接请求会注册到多路复用器上,多路复用器轮询到连接有 IO 请求就进行处理:

NIO 的数据是面向缓冲区 Buffer 的,必须从 Buffer 中读取或写入。

所以完整的 NIO 示意图:

NIO 完整示意图

可以看出,NIO 的运行机制:

  • 每个 Channel 对应一个 Buffer。
  • Selector 对应一个线程,一个线程对应多个 s。
  • Selector 会根据不同的事件,在各个通道上切换。
  • Buffer 是内存块,底层是数据。

AIO:JDK 7 引入了 Asynchronous I/O,是异步不阻塞的 IO。在进行 I/O 编程中,常用到两种模式:Reactor 和 Proactor。Java 的 NIO 就是 Reactor,当有事件触发时,服务器端得到通知,进行相应的处理,完成后才通知服务端程序启动线程去处理,一般适用于连接数较多且连接时间较长的应用。

PS:关于同步阻塞 IO、同步不阻塞 IO、异步不阻塞 IO 的相关概念可以查看:面试字节,被操作系统问挂了

文章作者: stormling
文章链接: http://www.stormling.top/posts/55137.html
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 码农Stormling!
Java基础核心
cover of previous post
上一篇
Java系列(五)| 序列化、泛型、注解、反射
序列化什么是序列化?什么是反序列化?什么是序列化,序列化就是把 Java 对象转为二进制流,方便存储和传输。 所以反序列化就是把二进制流恢复成对象。 序列化和反序列化 类比我们生活中一些大件物品的运输,运输的时候把它拆了打包,用的时候再拆包组装。 Serializable 接口有什么用? 这个接口只是一个标记,没有具体的作用,但是如果不实现这个接口,在有些序列化场景会报错,所以一般建议,创建的 JavaBean 类都实现 Serializable。 serialVersionUID 又有什么用? serialVersionUID 就是起验证作用。 private static final long serialVersionUID = 1L; 我们经常会看到这样的代码,这个 ID 其实就是用来验证序列化的对象和反序列化对应的对象 ID 是否一致。 这个 ID 的数字其实不重要,无论是 1L 还是 IDE 自动生成的,只要序列化时候对象的 serialVersionUID 和反序列化时候对象的 serialVersionUID 一致的话就行。 如果没有显示指定...
cover of next post
下一篇
Java系列(三)| 常用类
StringString 是 Java 基本数据类型吗?可以被继承吗? String 是 Java 基本数据类型吗? 不是。Java 中的基本数据类型只有 8 个:byte、short、int、long、float、double、char、boolean;除了基本类型(primitive type),剩下的都是引用类型(reference type)。 String 是一个比较特殊的引用数据类型。 String 类可以继承吗? 不行。String 类使用 final 修饰,是所谓的不可变类,无法被继承。 String 和 StringBuilder、StringBuffer 的区别? String:String 的值被创建后不能修改,任何对 String 的修改都会引发新的 String 对象的生成。 StringBuffer:跟 String 类似,但是值可以被修改,使用 synchronized 来保证线程安全。 StringBuilder:StringBuffer 的非线程安全版本,性能上更高一些。 String str1 = new String(“abc”)...
相关推荐
cover
2021-09-19
Java系列(五)| 序列化、泛型、注解、反射
序列化什么是序列化?什么是反序列化?什么是序列化,序列化就是把 Java 对象转为二进制流,方便存储和传输。 所以反序列化就是把二进制流恢复成对象。 序列化和反序列化 类比我们生活中一些大件物品的运输,运输的时候把它拆了打包,用的时候再拆包组装。 Serializable 接口有什么用? 这个接口只是一个标记,没有具体的作用,但是如果不实现这个接口,在有些序列化场景会报错,所以一般建议,创建的 JavaBean 类都实现 Serializable。 serialVersionUID 又有什么用? serialVersionUID 就是起验证作用。 private static final long serialVersionUID = 1L; 我们经常会看到这样的代码,这个 ID 其实就是用来验证序列化的对象和反序列化对应的对象 ID 是否一致。 这个 ID 的数字其实不重要,无论是 1L 还是 IDE 自动生成的,只要序列化时候对象的 serialVersionUID 和反序列化时候对象的 serialVersionUID 一致的话就行。 如果没有显示指定...
cover
2021-09-18
Java系列(三)| 常用类
StringString 是 Java 基本数据类型吗?可以被继承吗? String 是 Java 基本数据类型吗? 不是。Java 中的基本数据类型只有 8 个:byte、short、int、long、float、double、char、boolean;除了基本类型(primitive type),剩下的都是引用类型(reference type)。 String 是一个比较特殊的引用数据类型。 String 类可以继承吗? 不行。String 类使用 final 修饰,是所谓的不可变类,无法被继承。 String 和 StringBuilder、StringBuffer 的区别? String:String 的值被创建后不能修改,任何对 String 的修改都会引发新的 String 对象的生成。 StringBuffer:跟 String 类似,但是值可以被修改,使用 synchronized 来保证线程安全。 StringBuilder:StringBuffer 的非线程安全版本,性能上更高一些。 String str1 = new String(“abc”)...
cover
2021-09-17
Java系列(二)| 面向对象
面向对象和面向过程的区别? 面向过程 :面向过程就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候再一个一个的一次调用就可以。 面向对象 :面向对象,把构成问题的事务分解成各个对象,而建立对象的目的也不是为了完成一个个步骤,而是为了描述某个事件在解决整个问题的过程所发生的行为。目的是为了写出通用的代码,加强代码的重用,屏蔽差异性。 用一个比喻:面向过程是编年体;面向对象是纪传体。 面向对象有哪些特性...
cover
2021-09-16
Java系列(一)| 基础语法
Java 概述什么是 Java?Java 是一门面向对象的编程语言,不仅吸收了 C++ 语言的各种优点,还摒弃了 C++ 里难以理解的多继承、指针等概念,因此 Java 语言具有功能强大和简单易用两个特征。Java 语言作为静态面向对象编程语言的优秀代表,极好地实现了面向对象理论,允许程序员以优雅的思维方式进行复杂的编程 。 Java 语言有哪些特点?Java 语言有很多优秀(可吹)的特点,以下几个是比较突出的: Java 语言特点 面向对象(封装,继承,多态); 平台无关性:Java 是 “【一次编写,到处运行(Write Once,Run any Where)】” 的语言,因此采用 Java 语言编写的程序具有很好的可移植性,而保证这一点的正是 Java 的虚拟机机制。在引入虚拟机之后,Java 语言在不同的平台上运行不需要重新编译。 支持多线程:C++ 语言没有内置的多线程机制,因此必须调用操作系统的多线程功能来进行多线程程序设计 编译与解释并存; JVM、JDK 和 JRE 有什么区别?JVM:Java Virtual Machine,Java 虚拟机,Java...

评论
ValineGitalk
avatar
stormling
文章
42
标签
25
分类
21
Follow Me
公告
欢迎大家来到Stormling博客
目录
  1. 1. Java 中异常处理体系?
  2. 2. 异常的处理方式?
  3. 3. 三道经典异常处理代码题
  • I/O
    1. 1. Java 中 IO 流分为几种?
    2. 2. 既然有了字节流, 为什么还要有字符流?
    3. 3. BIO、NIO、AIO?
  • 最新文章
    面向八股文面试专场
    面向八股文面试专场2025-01-22
    【每日早报】-2025-01-21 - 星期二
    【每日早报】-2025-01-21 - 星期二2025-01-21
    规则引擎 Drools 8+ 快速入门
    规则引擎 Drools 8+ 快速入门2024-12-11
    数据库系列(二) | Mybatis Plus 3.0+快速入门
    数据库系列(二) | Mybatis Plus 3.0+快速入门2024-12-09
    分布式系列(二) | Redisson分布式锁
    分布式系列(二) | Redisson分布式锁2024-12-05
    ©2019 - 2025 By stormling
    码农Stormling程序员,关注公众号【码农Stormling】回复【面试】获取最全面试pdf
    搜索
    数据加载中