java scoket超时 java 超时异常_java 代码段 执行超时 抛异常


Java异常,看这篇文章就够了 | xyzliu106.52.132.118:8090

java scoket超时 java 超时异常_JVM_02


我们能学到什么

1、明确什么是异常 (重点)
2、能辨识出常见的异常及其含义。 (熟悉+)
3、理解异常产生的原理 (了解)
4、能处理异常 (重点)
5、能够自定义异常类型 (熟悉)

异常的概念

异常是在程序中导致程序中断运行的一种指令流。

当异常出现时就说明我们的程序出现了不正常的情况,应该立即予以修复,决不应该用"正常"的态度来看待异常。说地绝对一点异常就是某种意义上的错误,就是问题,它可能会导致程序失败。

异常是如何产生的

1、发生了异常(JVM根据异常的情况,创建了一个异常对象—包含了异常信息)
2、main未处理,自动将异常抛给了main的调用者JVM
3、JVM对异常信息进行了响应(将异常信息显示到控制台,中断处理)

我们都知道程序是在JVM中运行的,当虚拟机执行我们的代码指令时发现不合理的地方便会提示我们,而采用的方式便是中断程序,使程序不再运行以免造成更大的错误。

但是虚拟机又是怎样告诉我们发生的各种各样的问题呢?

Java从1995年5月出现到现在,在二十多年间的发展过程中许多的开发者遇到了各种各样的问题,当同样的问题发生地多了以后Java官方便对其进行了整理,包括其早期设想到的以及后来实际开发中大家遇到的,整理完成以后列了很多很多异常的类型

因为Java是一门纯面象对象的语言,因此它告诉我们出现异常的方式也是通过对象实现的。例如下面的代码中,当我们除数输入为零后,当JVM执行到x/y语句时发现除数为零,于是创建了一个ArithmeticException(算数异常)类型的对象,其中保存的信息便是/ by zero(除数不能为零),然后再将该对象传递给我们,便出现了如下图所示的异常:

当JVM执行指令发现错误时,便将出现错误的语句做了一个创建异常对象的操作


package run.xyzliu.section6;
import java.util.Scanner;
public class Test {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        System.out.println("请输入被除数:");
        int x = input.nextInt();
        System.out.println("请输入除数:");
        int y = input.nextInt();
        System.out.println(x/y);
    }
}


java scoket超时 java 超时异常_JVM_03

JVM将出现错误语句创建成了异常对象

异常的体系结构

异常指的是Exception , Exception类, 在Java中存在一个父类Throwable(可能的抛出) Throwable存在两个子类: 1.Error:表示的是错误,是JVM发出的错误操作,只能尽量避免,无法用代码处理。 2.Exception:一般表示所有程序中的错误,所以一般在程序中将进行try…catch的处理


java scoket超时 java 超时异常_JVM_04

异常的体系结构

捕获异常

在上面的代码中,如果main()方法中没对异常进行处理,JVM创建完异常对象后便将其通过类似返回的方式将异常对象抛给调用main()方法的人,即JVM。当JVM发现其创建的异常对象又回到自己这里以后便采取中断程序的方案迫使开发者进行修改。

那我们该如何避免JVM中断程序呢?

在异常对象返回给JVM的过程中将其拦截,这个过程对我们处理异常来说便是—捕获异常,异常捕获到后便可对其采取应对措施。

处理异常

1、try-catch处理异常

try-cache捕获并处理异常的格式

如果要想对异常进行处理,则必须采用标准的处理格式,处理格式语法如下:

try {
// 有可能发生异常的代码段
} catch(异常类型1 对象名1){
// 异常的处理操作
} catch(异常类型2 对象名2){
// 异常的处理操作
} ...
finally{
// 异常的统一出口 }

特殊的多异常捕获写法:

catch(异常类型1 | 异常类型2 对象名){
//表示此块用于处理异常类型1 和 异常类型2 的异常信息
}

try+catch的处理流程

1、 一旦产生异常,则系统会自动产生一个异常类的实例化对象。 2、 那么,此时如果异常发生在try语句,则会自动找到匹配的catch语句执行,如果没有在try语句中,则会将异常抛出. 3、 所有的catch根据方法的参数匹配异常类的实例化对象,如果匹配成功,则表示由此catch进行处理。

2、throws关键字处理异常

在程序中异常的基本处理已经掌握了,但是随异常一起的还有一个称为throws关键字,此关键字主要在方法的声明上使用,表示方法中不处理异常,而交给调用处处理。 格式:

返回值 方法名称()throws Exception{
}

到目前为止,我们既可以通过try-catch处理异常,也可以使用throws抛出异常,那么我们在实际开发中应该选择哪种方法呢?他们的使用场景是怎样的呢?

throws关键字主要在方法的声明上使用,当是方法传递过来的参数导致的异常直接使用throws抛出即可,其余情况均要使用try-catch进行处理。

throw关键字

throw关键字表示在程序中人为的抛出一个异常,因为从异常处理机制来看,所有的异常一旦产生之后,实际上抛出的就是一个异常类的实例化对象,那么此对象也可以由throw直接抛出。

但是实际开发中开发者很少使用该关键字,因为既然已经知道了会出现异常那就直接解决呗,干嘛抛出个异常来提醒自己饭后再去解决呢?

finally关键字

在进行异常的处理之后,在异常的处理格式中还有一个finally语句,那么此语句将作为异常的统一出口,不管是否产生了异常,最终都要执行此段代码。

因此我们便可以在finally中关闭资源等操作,还可以通过其改变属性值。通过展示两段代码展示一下在final中修改属性引用的区别

关于finally关键字我们不仅要知道无论是否产生异常,最终都要执行其中的代码,还要知道什么时候不执行—当在try或catch中停止了JVM,则finally不会执行。比如电脑关机, 或通过如下代码退出JVMSystem.exit(0);

第一段代码:因为try{}中没有发现错误,因此执行完后便执行finally{}中的代码,


public class Demo{
    public static void main(String[] args){
        Person p = haha();
        System.out.println(p.age);  //打印结果为28
    }
    public static Person haha(){
        Person p = new Person();
        try{
            p.age = 18;
            return p;
        }catch(Exception e){
            return p;
        }finally {
            p.age = 28;
        }
    }
}


第二段代码:


public class Demo{
    public static void main(String[] args){
       int a = haha();
        System.out.println(a);  //打印结果为10
    }
    public static int haha(){
        int a = 10;
        try{
            return a;
        }catch(Exception e){
            return;
        }finally {
            a = 20;
        }
    }
}


我们仔细观察两端代码及其打印的结果,两段代码都是在try中设置数值,在finally中修改数值,可为什么打印出的结果却是不同的呢?关键在于数值类型

我们先了解一下try-fially中代码的执行流程:

将返回值存储起来, 等待返回 2、执行finally代码块 3、将之前 存储的返回值, 返回出去;

在第一段代码中,首先是方法入栈,在栈中建立引用 Person p,并在堆内存中开辟一块内存空间用于放置对象,结果是p指向该内存空间,即p的值是对象的地址。然后执行try中的代码,结果是给年龄赋值,并将返回值p的值复制一份保存起来等待返回,然后执行finally中的语句,将对象中的年龄改为28。

存储的返回值是对象的地址,所以返回的也是对象的地址,然后通过地址修改年龄

而第二段代码,首先是方法入栈,并在栈中建立栈内a = 10,然后执行try中的语句,结果是将a的值10复制一份存储起来等待返回,后然后执行finally中的语句,将a的设置为20,最后将存储的10返回出去。

存储的返回值的是最初设置的10,所以返回的是10,而不是修改后的20。

异常处理常见面试题

1、ry-catch-finally 中哪个部分可以省略? 答: catch和finally可以省略其中一个 , catch和finally不能同时省略 注意:格式上允许省略catch块, 但是发生异常时就不会捕获异常了,我们在开发中也不会这样去写代码.
2、try-catch-finally 中,如果 catch 中 return 了,finally 还会执行吗? 答:finally中的代码会执行 详解: 执行流程: 1、先计算返回值, 并将返回值存储起来, 等待返回 2、执行finally代码块 3、将之前存储的返回值, 返回出去; 需注意: 1、返回值是在finally运算之前就确定了,并且缓存了,不管finally对该值做任何的改变,返回的值都不会改变 2、finally代码中不建议包含return,因为程序会在上述的流程中提前退出,也就是说返回的值不是try或catch中的值 3、如果在try或catch中停止了JVM,则finally不会执行.例如停电- -, 或通过如下代码退出JVM:System.exit(0);