目录
Unparseable date:String -- Date
异常
- 异常:异常就是Java程序在运行过程中出现的错误
- 异常由来:问题也是现实生活中一个具体事务,也可以通过java的类的形式进行描述,并封装成对象。其实就是Java对不正常情况进行描述后的对象体系
异常分类图解
Class Throwable
查看API文档我们知道:
public class Throwable extends Object implements Serializable
Throwable
类是Java语言中所有错误和异常的Throwable
类。 只有作为此类(或其一个子类)的实例的对象由Java虚拟机抛出,或者可以由Javathrow
语句抛出。 类似地,只有这个类或其子类可以是catch
子句中的参数类型。 对于异常,编译时检查的目的Throwable
和任何子类Throwable
,是不是也无论是子类RuntimeException或Error被视为检查的异常。通常使用两个子类的实例Error和异常来表示出现异常情况。 通常,这些实例是在特殊情况的上下文中新创建的,以便包括相关信息(如堆栈跟踪数据)。
throwable在创建时包含其线程的执行堆栈的快照。 它还可以包含一个消息字符串,其中提供有关错误的更多信息。 随着时间的推移,一个可以抛出的其他可抛物线可以被传播。 最后,throwable也可能包含一个原因 :另一个可抛出的,导致这个可抛出的构造。 这种因果信息的记录被称为链接的异常设施,因为原因本身可能有原因等等,导致“链”的异常,每个异常都由另一个导致。
抛出一个原因的一个原因是抛出它的类被构建在较低层次的抽象之上,上层的操作由于下层的故障而失败。 让下层投掷的投掷物向外传播是不好的设计,因为它通常与上层提供的抽象无关。 此外,这样做会将上层的API与其实现的细节相结合,假设较低层的异常是被检查的异常。 抛出“包装异常”(即,包含原因的异常)允许上层将故障的细节传达给其呼叫者,而不会导致这些缺点之一。 它保留了更改上层实现的灵活性,而不改变其API(特别是其方法抛出的一组异常)。
throwable可能有一个原因的第二个原因是抛出它的方法必须符合通用接口,该接口不允许该方法直接引用原因。 例如,假设持久集合符合Collection接口,并且其持久性在java.io顶部
java.io
。 假设add
方法的内部可以抛出一个IOException 。 实施可以在细节沟通IOException
同时符合它的调用者Collection
通过封装接口IOException
在适当的未经检查的异常。 (持久集合的规范应该表明它能够抛出这种异常。)一个原因可以通过两种方式与一个可抛出的关联:通过构造函数将原因作为参数,或通过initCause(Throwable)方法。 希望允许原因与他们相关联的新的可抛出类可以提供构造函数,这些构造函数可以引导和委派(或间接地)到
Throwable
函数之一的Throwable中。 因为initCause
方法是公开的,它允许一个原因与任何可抛出的,即使是“传统的可抛出”相关联,其实现早于将异常链接机制添加到Throwable
。按照惯例,类
Throwable
及其子类有两个构造函数,一个不String
参数,另一个String
函数采用可用于生成详细消息的String
参数。 此外,那些可能与之相关联的原因的子类应该有两个构造函数,一个是Throwable
(原因),另一个是String
(详细信息)和一个Throwable
(原因)。
Java中的异常:Throwable
查看API文档我们知道:
严重的问题:Error,一般情况下我们不处理这样的问题,举例OOM,Out Of Memory,内存溢出的问题。
异常Exception:
- 运行时期异常:RuntimeException这样的问题我们也不处理,因为这样类似的问题 一般情况下都是由于你的代码不够严谨导致的。
- 编译时期异常:除了不是RuntimeException的,都是编译时期异常,必须要处理,如果你不处理 编译不通过,无法运行。
一些异常的例子
ArithmeticException:by/zero
参考代码:
public class ExceptionDemo1 {
public static void main(String[] args) {
int a = 10;
int b = 0;
System.out.println(a/b);
}
}
ArithmeticException: / by zero
参考代码:
public class ExceptionDemo1 {
public static void main(String[] args) {
int a = 10;
int b = 0;
try {
System.out.println("有异常0不能作为除数。");
}catch (ArithmeticException e){
System.out.println(a/b);
}
}
}
输出结果:
有异常0不能作为除数。
Unparseable date:String -- Date
参考代码:
import java.text.SimpleDateFormat;
import java.util.Date;
public class ExceptionDemo2 {
public static void main(String[] args) {
//日期类
Date date = new Date();
System.out.println(date);
//日期转换是我们开发中经常使用的
//HH大写的表示24小时制度
//hh小写表示12小时制度
// SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
// String s = sdf.format(date);
// System.out.println(s);
//String -- Date
String s = "2021-12-24";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
date = sdf.parse(s);
}
}
NullPointerException : 空指针异常
参考代码:
public class ExceptionDemo3 {
public static void main(String[] args) {
//NullPointerException
int[] arr = null;
System.out.println(arr.length);
}
}
在上面上述3个代码例子中,都是以后我们做开发经常遇见的异常,那么我们该如何对这些异常进行处理呢?
异常处理方式
try...catch...finally处理格式
格式1:
try{
可能会出现问题的代码;
}catch(异常的类名 变量名){
针对问题的一些处理;
}finally{
无论报不报错都会执行的代码;
(一般情况下,这里放的都是一些释放资源的代码)
}
变形格式
格式2:
try{
可能会出现问题的代码;
}catch(异常的类名 变量名){
针对问题的一些处理;
}
处理多个异常的格式:
try{
可能会出现问题的代码1;
可能会出现问题的代码2;
}catch(异常类的类名1 变量名1){
针对问题的一些处理;
}catch(异常类的类名2 变量名2){
针对问题的一些处理;
}
多个catch注意事项
- 能明确异常类型的时候,尽量明确类型,不要用父类大的做处理
- catch与catch之间的异常是平级关系,多个catch异常类之间没有先后顺序关系,一旦出现了一个父类继承父类关系,父类必须在最后
- 一旦try里面的代码出现了问题,就会去匹配catch里面的异常,继续执行程序try...catch..后面的代码,try里面的代码,try里面的代码就停在了报错的那一步。
参考代码:
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class ExceptionDemo4 {
public static void main(String[] args) {
int a =10;
int b = 0;
if (b==0){
System.out.println("除数不能为0!!!");
}else {
System.out.println(a/b);
}
//String -- Date
String s = "2021-12-24 20";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
try {
Date date = sdf.parse(s);
} catch (ParseException e) {
System.out.println("日期转换出现错误啦!!!");
}
int arr[] = null;
try {
System.out.println(arr.length);
}catch (NullPointerException e){
System.out.println("空指针异常!!!");
}
}
}
除数不能为0!!!
日期转换出现错误啦!!!
空指针异常!!!
参考代码:
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class ExceptionDemo5 {
public static void main(String[] args) {
int[] arr = null;
String s = "2021-12-24 21";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
try {
Date date = sdf.parse(s);
//如果在try里面的代码中间报错了
//会直接匹配catch里面的异常
//try中剩下的代码不会执行
System.out.println(date);
System.out.println(arr[4]);
System.out.println(arr.length);
}catch (ParseException|NullPointerException e){
System.out.println("有内鬼,终止交易!");
}
System.out.println("圣诞节快乐写代码!");
}
}
输出结果:
有内鬼,终止交易!
圣诞节快乐写代码!
异常中需要掌握的方法
getMessage()
查看API文档我们知道:
public String getMessage()返回此throwable的详细消息字符串。
结果
这个
Throwable
实例的详细消息字符串(可能是null
)。
参考代码:
public class ExceptionDemo6 {
public static void main(String[] args) {
int a = 10;
int b = 0;
//ArithmeticException
try {
System.out.println(a/b);
}catch (ArithmeticException e){//ArithmeticException e = new ArithmeticException();
//打印的是出现异常的原因
System.out.println(e.getMessage());
}
}
}
输出结果:
/ by zero
获取异常信息,返回字符串
toString()
查看API文档我们知道:
public String toString()返回此可抛出的简短描述。 结果是:如果
getLocalizedMessage
返回null
,那么只返回类名。重写:
结果
这个throwable的字符串表示形式。
- 这个对象的类的name
- “:”(一个冒号和一个空格)
- 调用这个对象的getLocalizedMessage()方法的结果
参考代码:
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class ExceptionDemo7 {
public static void main(String[] args) {
int a = 10;
int b = 0;
//ArithmeticException
try {
System.out.println(a/b);
}catch (ArithmeticException e){//ArithmeticException e = new ArithmeticException();
//java.lang.ArithmeticException: / by zero
//异常的类名: 产生问题的原因
System.out.println(e.toString());
}
}
}
输出结果:
java.lang.ArithmeticException: / by zero
获取异常类名和异常信息,返回字符串
printStackTrace()
查看API文档我们知道:
这么长一大段,让我们通过代码案例观察一下吧
参考代码1:
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class ExceptionDemo7 {
public static void main(String[] args) {
int a = 10;
int b = 0;
//ArithmeticException
try {
System.out.println(a/b);
}catch (ArithmeticException e){//ArithmeticException e = new ArithmeticException();
}
String s = "2021-12-24 14";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
try {
Date date = sdf.parse(s);
} catch (ParseException e) {
e.printStackTrace();
}
System.out.println("hello");
}
}
参考代码2:
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class ExceptionDemo7 {
public static void main(String[] args) {
int a = 10;
int b = 0;
//ArithmeticException
try {
System.out.println(a/b);
}catch (ArithmeticException e){//ArithmeticException e = new ArithmeticException();
e.printStackTrace();
}
String s = "2021-12-24 14";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
try {
Date date = sdf.parse(s);
} catch (ParseException e) {
e.printStackTrace();
}
System.out.println("hello");
}
}
通过观察发现,和我们之前不做任何处理的时候,JVM自动默认处理的打印异常结果是一样的,我们不能不处理,如果不处理一旦发生异常,后面的代码不会运行,我们做了处理之后,后面的代码才会正常运行。
🧡到底啦!给靓仔一个关注吧!祝大家圣诞节快乐!💛