java异常——异常分类+声明已检查异常+如何抛出异常+自定义异常类

【0】README

0.1) 本文描述+源代码均 转自 core java volume 1, 旨在理解 java异常——异常分类+声明已检查异常+如何抛出异常+自定义异常类 的相关知识;
0.2)异常处理的任务: 就是将控制权从错误产生的地方转移给能够处理这种case 的错误处理器;
0.3)为了能够在程序中处理异常情况, 必须研究程序中可能会出现的错误和问题,以及哪类问题需要关注:

  • 0.3.1)用户输入错误:用户输入 URL , 而其语法却不正确;
  • 0.3.2)设备错误:硬件不总是让它做什么,它就做什么, 比如打印机关掉了;
  • 0.3.3)物理限制:磁盘满了,可用存储空间已被用完;
  • 0.3.4)代码错误:程序方法有可能无法正确执行;

【1】异常分类

1.1)java中, 异常都是派生于 Throwable 类的一个实例: 且如果java内置的异常类不能够满足需求,用户可以自己创建异常类;(下图显示了 java异常层次结构的简化图)
这里写图片描述

对上图的分析(Analysis)

  • A1)Error类层次结构:描述了java运行时系统的内部错误和资源耗尽错误, 这种case 很少出现;
  • A2)Exception层次结构:划分成两个分支的规则是: 由程序错误导致的异常属于 RuntimeException, 而程序本身没有问题, 但由于像 IO错误这类问题导致的异常属于其他异常;

1.2)派生于RuntimeException 的异常包含下面几种 Cases(运行时异常的几种 cases), 这属于未检查类异常(unchecked):

  • C1)错误的类型转换;
  • C2)数组访问越界;
  • C3)访问空指针;

1.3)不是派生于 RuntimeException 的异常包括:

  • C1)试图在文件尾部后面读取数据;
  • C2)试图打开一个不存在的文件;
  • C3)试图根据给定的字符串查找class 对象, 而这个字符串表示的类并不存在;

Attention)

  • A1)如果出现 RuntimeException 异常, 那么就一定是你的问题了, 这是一条相当有道理的规则;
  • A2)应该通过检测数组下标是否越界来避免 ArrayIndexOutofBoundException 异常;应该通过在变量使用前检测是否为空来杜绝 NullPointerException 异常的发生;

1.4)异常分类:

  • 1.4.1)未检查异常(不需要throw 抛出的异常,这是程序运行过程中出现的错误): java语言规范 派生于 Error类 或 RuntimeException类的所有异常称为 未检查异常(unchecked);
  • 1.4.2)已检查异常(需要显式抛出的异常):所有其他的异常称为 已检查异常(checked);
    这里写图片描述

【2】声明已检查异常

2.1)如果遇到了无法处理的case , java抛出一个异常, 这个道理很简单: 一个方法不仅需要告诉编译器将要返回什么值, 还要告诉编译器有可能发生什么错误;例如, 一段读取文件 的代码知道有可能读取的文件不存在, 或者内容为null , 因此, 试图处理文件信息的代码就需要通知编译器可能会抛出 IOException 类的异常;
2.2)方法应该在其首部声明所有可能抛出的 异常, 这样可以从首部反映出这个方法可能抛出哪类已检查异常:如,

public FileInputStream(String name) throws FileNotFoundException 

, 如果上述代码真的抛出了异常, 那么运行时系统就会开始搜索异常处理器, 以便知道如何处理 FileNotFoundException 对象;
2.3)在自己编写方法时, 不必将所有 可能抛出的异常全部都进行声明。 至于什么时候需要在方法中用 throws 子句声明异常, 什么异常必须使用 throws 子句声明, 需要记住下面遇到的 4种 Cases 应该抛出异常:

  • C1)调用一个抛出已检查异常的方法, 例如, FileInputStream 构造器;
  • C2)程序运行过程中发现错误, 并且利用 throw 语句抛出一个已检查异常;
  • C3)程序出现错误, 例如, a[-1]=0 会抛出一个 ArrayIndexOutOfBoundsException 这样的未检查异常;
  • C4) java 虚拟机和运行时库出现的内部错误;

  • 2.3.1)如果出现前两种cases 之一, 则必须告诉调用这个方法的程序员有可能抛出异常。因为任何一个抛出异常的方法都有可能是一个死亡陷阱。如果没有处理器捕获这个异常, 当前执行的线程就会结束;

  • 2.3.2)对于那些可能被其他人使用的 java方法, 应该根据异常规范, 在方法的首部声明这个方法可能抛出的异常;
class MyClass
{public Image loadImage(String s) throws IOException
}
  • 2.3.3)如果一个方法有可能抛出多个已检查异常, 那么就必须在方法的首部列出所有的异常类。每个异常类之间用逗号隔开:
class MyClass
{public Image loadImage(String s) throws FileNotFoundException, EOFException
}
  • 2.3.4)但是,不需要 声明java 的内部错误, 即从Error 继承的错误。因为任何程序代码都具有抛出那些异常的潜能, 而我们对其没有任何控制能力;
  • 2.3.5)同样, 也不应该声明从 RuntimeException 继承的那些未检查异常:(因为, 这些错误完全在我们的控制之下, 如果特别关注数组下标引发的错误, 就应该将更多的时间花在 修正程序的错误上, 而不是说明这些错误发生的可能性上) //bad style 错误的异常抛出格式(RuntimeException属于未检查类异常,是不需要throw 抛出的异常,这是程序运行过程中出现的错误)
class MyClass
{public Image loadImage(String s) throws ArrayIndexOutOfBoundsException //bad style 错误的异常抛出格式
}

Conclusion)

  • C1)总之, 一个方法必须 声明 所有可能抛出的已检查异常, 而未检查异常要么不可控制(Error), 要么就应该避免发生(RuntimeException)。 如果方法没有声明所有可能发生的已检查异常, 编译器就会给出一个错误消息;
  • C2)当然,除了声明异常之外, 还可以捕获异常, 这样会使得异常不被抛出到方法之外,也不需要 throws 规范;(稍后, 我们来讨论如何决定一个异常是被捕获, 还是被抛出让其他的处理器进行处理)

Warning)

  • W1)如果在子类中覆盖了超类中的一个方法, 子类方法中声明的已检查异常不能比超类方法中声明的异常更通用(也就是说, 子类方法中可以抛出更特定的异常, 或者根本不抛出任何异常)
  • W2)特别需要说明的是: 如果超类方法没有抛出任何已检查异常, 子类也不能抛出任何已检查异常;

  • 2.3.6)如果类中的一个方法声明将会抛出一个异常, 而这个异常是某个特定类的实例时, 则这个方法就有可能抛出一个这个类的异常, 或者这个类的任意一个子类的异常;看个荔枝:

    • 例如: FileInputStream 构造器声明将有可能抛出一个 IOException异常,然而并不知道具体是哪种IOException异常, 它既可能是 IOException异常,也可能是其子类的异常,例如, FileNotFoundException;

【3】如何抛出异常

3.1)首先要决定抛出什么类型异常 。如, EOFException异常描述为“在输入过程中, 遇到了一个未预期的EOF后 的信号”;
3.2)下面抛出这个异常的语句:

throw new EOFException();
或者, 
EOFException e = new EOFException();
throw e;
  • 3.2.1)EOFException类还有一个字符串参数的构造器。这个构造器更加详细的描述异常出现的情况:
String gripe = "content-length" + len + ", received: " + n;
throw new EOFException(gripe);
  • 3.2.2)在以下cases 下, 一旦方法抛出异常, 这个方法就不可能返回到调用者了;
    • case1)找到一个合适的异常类;
    • case2)创建这个类的一个对象;
    • case3)将对象抛出;

【4】创建异常类(自定义异常类)

4.1)我们需要做的只是:定义一个派生于Exception的类, 或者派生于Exception子类的类;
4.2)定义的类应该包含两个构造器: 一个是默认的构造器, 另一个是带有详细描述信息的构造器(超类Throwable 的toString 方法将会打印出这些详细信息, 在调试中非常有用)

class FileFormatException extends IOException
{public FileFormatException() {} //1、默认构造器public FileFormatException(String gripe) //2、带有详细描述信息的构造器{super(gripe);}
}
  • 4.2.1)现在,就可以抛出自定义的异常类型了:
String readData(BufferedReader in) throws FileFormatException
{throw new FileFormatException();
}

[API] java.lang.Throwable 1.0

  • Throwable() :构造一个新的 Throwable 对象, 这个对象没有详细的描述信息;
  • Throwable(String msg):构造一个新的 Throwable 对象, 这个对象包含详细的描述信息;习惯上, 所有派生的异常类都支持一个默认构造器和一个带有描述信息的构造器;
  • String getMessage(): 获得Throwable 对象 的详细描述信息;

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

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

相关文章

quarkus_Quarkus入门

quarkusQuarkus – 一个针对OpenJDK HotSpot和GraalVM量身定制的Kubernetes本机Java堆栈,它是从最佳Java库和标准中精制而成的。 –是一个容器优先的框架,针对快速启动时间和低内存消耗进行了优化。 该框架基于许多流行的Java库构建,并且为构…

java异常——捕获异常+再次抛出异常与异常链

【0】README 0.1) 本文描述源代码均 转自 core java volume 1, 旨在理解 java异常——捕获异常再次抛出异常与异常链 的相关知识; 【1】捕获异常相关 1.1)如果某个异常发生的时候没有再任何地方进行捕获, 那程序就会…

java 类似xamarin_xamarin android如何将Java.Lang.Object类型转成C#类型

问题起源其实这个标题也可以换一个更准确一点,因为我遇到的问题是:xamarin android中的Class继承了Java.Lang.Object ,将json序列化成c#类型时发现无法赋值,序列化的格式没问题,但是Class的属性值没有复制成功。xamari…

java异常—— finally 子句+带资源的 try语句

【0】README 0.1) 本文描述源代码均 转自 core java volume 1, 旨在理解 java异常—— finally 子句带资源的 try语句 的相关知识; 【1】 finally 子句相关 1.1)产生资源回收问题:当代码抛出一个异常时, …

jep290涉及jdk版本_JDK 13中的JEP 355文本块

jep290涉及jdk版本JDK 13已于2019年9月17日上线GA, 此处列出了重要的新功能。 新功能之一是“文本块”。 这样可以轻松地编写多行字符串,而不必在拆分为不同行的同时进行串联。 让我们快速了解创建多行字符串的不同方式: String aBlock &q…

java单例注册表_Java单例模式(Singleton)

单例模式主要用于:有一些对象我们只需要一个,比如:线程池、缓存、对话框、处理偏好设置、注册表对象、日志对象以及配置文件对象、数据库连接对象等等。单例模式常用于管理共享资源,例如:数据库连接或者线程池。Java S…

java异常——分析堆栈跟踪元素+使用异常机制的技巧

【0】README 0.1) 本文描述源代码均 转自 core java volume 1, 旨在理解 java异常——分析堆栈跟踪元素使用异常机制的技巧 的相关知识; 【1】分析堆栈跟踪元素相关 1.1)堆栈跟踪: 它是一个方法调用过程的列表&#…

jdk8 npe_JDK 14中更好的NPE消息

jdk8 npe我的2019年3月博客文章“ Java会出现更好的默认NullPointerException消息吗? ”的撰写是为了获得更好的NullPointerException消息的JEP 草案尚未针对特定的JDK版本。 此后,该JEP草案成为JEP 14的 目标 JEP 358(“ Helpful NullPointe…

开源相册系统Java_基于JAVA的B/S网络相册管理系统

每天记录学习,每天会有好心情。*^_^*今天和一个朋友共同完成了一个网络相册管理系统项目,我们在开发时选用的框架是SSM(MYECLIPSE)框架。我这个朋友知识有限,只会这个框架,哈哈,都是为了方便他。和往常一样选用简单又便…

java断言——Assertion

【0】README 0.1) 本文描述源代码均 转自 core java volume 1, 旨在理解 java断言——Assertion 的相关知识; 【1】使用断言 1.1)断言机制: 允许在测试期间向代码中插入一些检查语句。 当代码发布时, 这些…

常见的并发模型_两个常见的并发错误

常见的并发模型作为Baeldung的编辑,我很高兴与一位作者一起撰写有关Java通用并发陷阱的文章。 这是一本不错的书,但是假设开发人员具有一定的能力。 我已经看到了几件即时并发失败的事情。 它们很容易添加到代码中,并保证为您提供奇怪的结果…

java 哈希一致算法_一致哈希算法Java实现

一致哈希算法(Consistent Hashing Algorithms)是一个分布式系统中常用的算法。传统的Hash算法当槽位(Slot)增减时,面临所有数据重新部署的问题,而一致哈希算法确可以保证,只需要移动K/n份数据(K为数据总量, n为槽位数量),且只影响…

java日志——基本日志+高级日志

【0】README 0.1) 本文描述源代码均 转自 core java volume 1, 旨在理解 java日志——基本日志高级日志 的相关知识; 【1】记录日志 1.1)出现的问题和解决方法: 1.1.1)出现的问题:在我们调试…

java模式匹配_用Java匹配模式

java模式匹配如果您使用的是Java,那么您很有可能以前已经看过它的模式匹配。 String#matches(String)方法在内部使用Pattern类型,该类型包含更复杂的功能: 通过编译正则表达式来创建Pattern 。 该模式与任何输入字符串匹配,并且可…

java在frame怎么计时_java – 退出jframe时的Swing stop计时器

我有一个特定的任务,我按计划的时间间隔运行.基本上我在JFrame中的Label上显示相机.但是,当我退出JFrame时,应用程序似乎运行.我怎么能阻止它?我已经删除了代码的细节,只是将相关部分留在了public class TaskCLass extends JFrame {JPanel p;JLabel l;Timer timer;p…

java日志——修改日志管理器配置+日志本地化

【0】README 0.1) 本文描述源代码均 转自 core java volume 1, 旨在理解 java日志——修改日志管理器配置日志本地化 的相关知识; 【1】修改日志管理器配置 1.1)可以通过编辑配置文件来修改日志系统的各种属性。 在默认情况下&a…

jpa embedded_JPA @Embeddable和@Embedded

jpa embedded介绍: 作为一个面向对象的开发人员,我们希望避免使用带有大量不相关字段的大型类。 因此,我们可能经常感到有必要使用多个对象来表示JPA实体。 在本快速教程中,我们将学习如何使用JPA或Hibernate中的Embedded和Embed…

jdk内置线程实例_EA问题的JDK14实例

jdk内置线程实例Tagir Valeev最近发布了一条有关即将发布的Java JDK14版本的预览功能的推文: #Java14模式匹配将名称隐藏带入了更高的疯狂程度。 在这里,我为FLAG字段添加或删除了final修饰符,该修饰符仅在不可达的if分支中访问。…

intro to Apache Log4j 2

【0】README 0.1)本文作为 原文(http://logging.apache.org/log4j/2.x/)的译文,仅作参考, 旨在了解 Log4j 2 的相关知识 ; 0.2) Apache Log4j 2 是Log4j的升级版,并对其前任Log4j …

php注册页面模板,选项卡式WordPress登陆注册模板

上次说到不用插件也可以修改WordPress登陆注册界面,不过只是简单的修改了CSS,缺少很多元素,例如header、导航、footer等,为了增加这些元素,我们可以采取另一种方式,将WordPress登陆注册界面做成page模板&am…