13 Java异常(异常过程解析、throw、throws、try-catch关键字)

news2024/9/21 20:22:19

文章目录

      • 13 异常
        • 13.1 异常概念
        • 13.2 异常的产生过程解析
        • 13.3 异常的阐释和处理
          • 13.3.1 throw关键字
          • 13.3.2 throws关键字
          • 13.3.3 try-catch代码块
          • 13.3.4 try-catch-finally代码块
            • Java中final、finally和finalize相似点和区别
          • 13.3.5 自定义异常

13 异常

13.1 异常概念

异常:指的是的程序在执行过程中,出现了非正常的情况,最终会导致JVM的非正常体停止

PS:在Java等面向对象的编程语言中,异常本身是一个类,产生异常就是创建异常对象并抛出一
个异常对象,Java处理异常的方式是中断处理【终止程序的运行】,还有异常指的并不是语法错
误,语法错了,编译时不会通过,不会产生字节码文件,根本不能运行

异常体系

异常机制其实是帮组我们找到程序中问题,异常的根类的是java.lang.Throwable,其下有两个子
类:java.lang.Error和java.lang.Exception,平时在说的程序异常其实是指java.lang.Excetption

请添加图片描述

  • Throwable体系

    • Error:严重的错误,无法通过处理的错误,只能事先避免【这就好比现实生活中“绝症”】
    • Exception:表示异常,异常产生后程序员是可以通过代码的方式进行纠正,使程序继续执行,是必要的处理。【这就好比现实生活中“感冒”】
  • Exception异常分类

    我们平时代码所说的异常其实就是指Exception,因为这类异常一旦出现,我们就要对代码进行更
    正和修复程序

    编译时异常:checked异常,在编译时期,就会进行检查,如果没有处理异常,则编译失败,造成程序是无法正确运行的【比如:日期格式化类中解析方法】

    运行时异常:runtime异常,在运行时期,检查异常,在编译时期,运行时异常不会编译器所检测(提示错误信息),只有当程序运行起来之后才会出现异常【比如:数组下标越界异常】

请添加图片描述

**在Java中编译时异常体现在于父类Exception,Java中运行时异常父类是RuntimeException,编译时异常是包含运行时异常即RuntimeException是Exception子类**
  • 演示:错误和异常【编译和运行】时

  •   public class ThrowableDemo {
          public static void main(String[] args) throws ParseException {
              //错误Error --》 死递归(访问无限调用自身,不能停止)【栈溢出错误】
              //java.lang.StackOverflowError ---》 栈溢出错误
              //show();
              //异常Exception --》
              // 运行时异常 ---> 数组下标越界异常 ---> ArrayIndexOutOfBoundsException
      //          int[] arr = new int[2];
      //           System.out.println(arr[3]);
              /*
              编译时异常 ---> 时间格式化解析方法 Unhandled exception: XXXXX ---> 提示是一个编译时异常需要处理
              java: 未报告的异常错误java.text.ParseException; 必须对其进行捕获或声明以便抛出
              编译时异常发现时,必须进行处理,否则无法正确执行代码
              */
              SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
              sdf.parse("1990-01-01");
          }
          public static void show(){
              show();
          }
      }
    

13.2 异常的产生过程解析

编写一个程序,程序会产生一个数组下标越界异常,分析以下异常的过程

请添加图片描述

13.3 异常的阐释和处理

13.3.1 throw关键字

在Java中,提供了一个throw关键字,它的作用可以抛出一个指定异常对象,throw关键字主要使用在方法的内部,用来抛出一个异常对象,将这个异常对象传递给方法的调用者,并结束方法的执行
PS:因为throw关键字在刚刚描述中说道了“结束方法执行”,所以throw可以当做一次return操作使用,return关键字作用“结束方法执行”,只不过throw返回是异常对象,return返回的是数据,在实际开发中,如果return已将将所有条件结果都进行了返回,但是方法依旧提示缺少一个return,此时就可以在最终的位置提供一个throw抛出一个异常

语法格式

throw new 异常类名(异常信息);
PS:异常名可以使用系统定义好的异常名,也可以使用自定义异常,异常信息是一个String字符串即
异常是因为什么原因出现的
例如:
throw new NullPointerException("因为数组arr引用为null,所以出现异常");
或者 --》在使用throw 抛出异常信息时最常用异常类型
throw new RuntimeException("程序运行时出错,某些数据没有初始化");
  • 需求:提供一个Person类,在Person下提供2个子类Man和Woman,在提供一个类,这个类负责通过参数创建对应类的对象操作

    //抽象父类 ---> Person
    public abstract class Person {
        private String name;
        private String sex;
        public Person(){}
        public Person(String name, String sex) {
            this.name = name;
            this.sex = sex;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public String getSex() {
            return sex;
        }
        public void setSex(String sex) {
            this.sex = sex;
        }
    }
    class Man extends Person{
        public Man() {
        }
        public Man(String name, String sex) {
            super(name, sex);
        }
    }
    class Woman extends Person{
        public Woman() {
        }
        public Woman(String name, String sex) {
            super(name, sex);
        }
    }
    class FactoryPerson{
        public static Person createPerson(String sex){
            switch (sex){
                case "男人":
                    return new Man();
                case "女人":
                    return new Woman();
                default:
    //throw 可以当做一个return使用
                    throw new RuntimeException("没有这个性别,无法创建....");
            }
        }
    }
    class Test{
        public static void main(String[] args) {
            Person man = FactoryPerson.createPerson("男人");
            System.out.println(man.getSex());
            Person oldMan = FactoryPerson.createPerson("老人");
            System.out.println(oldMan.getSex());
        }
    }
    
13.3.2 throws关键字

throws关键字的作用声明处理异常:使用throws关键字将异常信息标识出来,表示的当前方法不处理异常,而是提醒给调用方法者,让调用方法这来处理这个异常,如果调用方法这也不处理这异常,可以继续使用throws向上声明标识异常,直到遇到main方法还不处理,最终这个异常会被JVM虚拟所捕获处理,JVM处理方式就是停止JVM虚拟机,打印异常栈信息

PS:throws关键字只能在方法声明的位置使用即小括号后

访问权限修饰符 [其他修饰符] 返回值类型 方法名(参数列表)throws 异常类名1,异常类名2...{
        方法体
        returnthrow 关键字
        }
PSthrows 关键字后面的异常可以有多个,每个异常之间使用[,]分隔
  • 需求:使用日起格式化类,解析字符串到Date对象

    public class ParseExceptionDemo {
        //此时异常声明标识是在main方法上,如果一旦触发异常必然是JVM虚拟停止并打印异常信息
        public static void main(String[] args) throws ParseException, IOException {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            String time = "1990-01-01";
            Date parse = sdf.parse(time);
            //因为在show方法上声明标识了一个编译时异常IOException,所以只要调用show方法就需要
            处理这个异常
            show();
        }
        public static void show()throws IOException{
            //Unhandled exception: java.io.IOException-->因为IOException是编译异常
            //需要外界调用按方法时,知晓这个内部会出现异常问题
            throw new IOException();
        }
    }
    

    总结:之所以会有异常产生是因为,方法体的内部使用throw关键字创建一个异常对象,抛出给调用者所以会产生异常,产生了异常之后可以使用throws关键字将这个异常声明标识,谁调用谁处理这个异常,这种方式也是开发中经常使用一种方式

    PS:尽量不要在main方法中声明标识异常,因为这样处理化就是JVM虚拟机,处理方式就是停止JVM虚拟机,打印异常信息所以我们尽量不要这样操作【虽然在开中都是这样做的】

13.3.3 try-catch代码块

捕获处理异常try…catch

当程序出现异常时,JVM处理方式是终止程序,打印【异常栈信息】,只要代码中出现异常时,异常后续提供代码是无法正常执行,所以除了throws声明标识异常信息之外, Java中还一种处理异常的方式,这种方式叫做【捕获处理异常】

捕获处理异常:对异常进行捕获处理,处理完成完成之后可以正常向下执行

语法格式

try{
编写代码,这里的代码是可能出现异常代码
}catch(异常类型 e){
提供当前处理异常代码
例如"【记录日志、打印异常信息、继续抛出异常等等】"
}
执行步骤:
1. 首先会先执行try代码块中代码,如果try代码块中代码出现了异常,那么就执行catch代码
块中代码,执行完毕之后,程序继续向下执行
2. 如果try代码块中代码没有出现异常,那么就不会执行catch代码块中代码,而是代码继续向
后执行

注意:

  1. try和catch都不能单独使用,必须连用
  2. catch后面提供小括号内,是当前要捕获的异常类型即try代码块中可能会出现异常类型

使用e即形成(异常类型 e)声明形式,相当于是创建了一个异常类型的对象e,e这个对象就代表这个异常类型,可以在catch代码块中使用

  1. try代码块中出现了异常,那么出现异常位置后面的代码都不会在执行了,而是转而执行catch代码块
  2. catch代码块是可以根据try中可能出现异常进行添加的,根据出现异常追加catch代码块,但是有一个原则,父类异常一定要放置到最后一个catch中,之前都应该是子类异常,如果将父类异常放置到第一个catch中,后续catch代码块都无法进行正常捕获操作【即父类异常将所有异常都接收了就会造成子类无法接收异常】

演示:

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class TryCatchDemo {
    public static void main(String[] args) {
    //提供出现异常代码
/*
int[] arr = new int[1];
System.out.println(arr[2]);//arr[2]出现了下标越界异常,没回造成当前后续代码无法
执行
System.out.println("我要是出现,证明程序执行到这行代码....");
*/
//提供try...catch代码块进行一个捕获处理 -->快捷键 ctrl+atl+t
/* try {
int[] arr = new int[1];
System.out.println(arr[2]);//arr[2]出现了下标越界异常,没回造成当前后续代码
无法执行
} catch (ArrayIndexOutOfBoundsException e) { //catch后面小括号内提供异常类
型,尽量是要对应捕获的异常类型
//提供除以异常方式
*//*
catch中确实可以做异常信息的提示,保证代码可以继续向后执行,但是只要出现以异常信
息
说明比代码出现了问题,虽然catch提供错误信息让代码继续执行,但并没有修改错误异常
代码
当我们发现出现异常信息时,需要及时的处理当前try中产生产生异常代码,否则虽然保证
代码正常执行,但是效果是错误的
*//*
//System.out.println("下标越界了,无法访问");
*//*
Throwable类中还提供一些方法可以方便不我们在catch代码块中进行错误信息的提示
getMessage() --> 打印异常信息【这个信息是系统提供(可能会很笼统)】
*//*
//System.out.println(e.getMessage());
*//*
开发阶段可以使用这个方法,但是项目上线之后就建议修改掉这个操作
方法printStackTrace() --> 打印异常栈信息包含了:【异常类型、异常原因、异常出
现位置】
*//*
e.printStackTrace();
}
System.out.println("我要是出现,证明程序执行到这行代码....");*/
        try {
            int[] arr = new int[1];
            System.out.println(arr[2]);//try代码块中如果代码出现异常,后续代码都无法执行【try中】
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            Date parse = sdf.parse("1990-10-10");
            System.out.println(parse);
        } catch (ParseException e) {
            e.printStackTrace();
        } catch (ArrayIndexOutOfBoundsException e){//try多个异常是,添加多个catch代码块进行异常追加捕获操作
            e.printStackTrace();
        }
        //提供多个catch的时候父类异常一定要在最后一个catch中,不要放置到之前否则无法正常捕获异常【异常子类】
        System.out.println("我被还行了");
        //ps: 在开发中如何处理多个catch的问题?因为代码中如果异常过多,那么会造成代码中catch语句非常多
        // 代码的简洁基本上就没有,所以面临这种多个异常需要处理是,就是直接提供父类异常抓取
        try {
            int[] arr = new int[1];
            System.out.println(arr[2]);//try代码块中如果代码出现异常,后续代码都无法执行【try中】
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            Date parse = sdf.parse("1990-10-10");
            System.out.println(parse);
        } catch (Exception e) { //这个父类Exception的原则就是谁出现异常就抓取谁吗,而且都可以匹配
            e.printStackTrace();
        }
        //提供多个catch的时候父类异常一定要在最后一个catch中,不要放置到之前否则无法正常捕获异常【异常子类】
        System.out.println("我被换行了");
    }
}

​ 总结:

  • 捕获异常处理,如果程序出现了异常,保证程序可以继续向后执行
  • 声明标识异常,如果程序出现了异常,程序就不会继续向后执行了

Java中异常机制的目的是为了提示开发人员,出现异常是代码出现问题需要进行修改,所以建议在编码阶段可以使用throws进行处理,在程序上线之后建议将出现异常位置使用try…catch方式进行处理这样可以保证对用户友好提示。

try…catch捕获异常之后,是对异常可以进行二次处理信息提示,但是只是提示了异常问题,不会对异常继续修改,所以开发时看到异常信息一定要修改代码才可以,才能保证保证正确执行

13.3.4 try-catch-finally代码块

finally语句代码快

finally语句代码块是配合try…catch语句代码块执行,finally语句代码块有一个特点,特点是无论是否发生异常,finally语句代码块【必然执行】,所以利用finally语句代码块的特点可以进行一些资源释放的操作【TCP/UDP网络连接、IO流文件的处理、JDBC进行数据库连接操作等等】

语法格式

try{
编写代码,这里的代码是可能出现异常代码
}catch(异常类型 e){
提供当前处理异常代码
例如"【记录日志、打印异常信息、继续抛出异常等等】"
}finally{
无论发生异常与否,这里都会执行
}
执行步骤:
	1. 首先会先执行try代码块中代码,如果try代码块中代码出现了异常,那么就执行catch代码
块中代码执行完毕之后,而是执行finally语句代码块中代码,然后程序继续向下执行
	2. 如果try代码块中代码没有出现异常,那么就不会执行catch代码块中代码,但是会执行
finally语句代码块中代码,然后程序继续向下执行
"ps: finally语句代码块不能单独使用"

演示:

import java.text.SimpleDateFormat;
import java.util.Date;

public class TryCatchFinallyDemo {
    public static void main(String[] args) {
        try {
            int[] arr = new int[1];
            //让代码出现异常
            System.out.println(arr[2]);
            //System.out.println(arr[0]);
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            Date parse = sdf.parse("1990-10-10");
            System.out.println(parse);
            //return; //---> 提供一个return关键字让方法结束 --》 return是不会阻止
            finally与就块执行
             // System.exit(1);---> 终止虚拟机 所以finally遇到它时候是不会执行
        } catch (Exception e) {
             // System.exit(1);
            e.printStackTrace();
        }finally {
            // 所以利用finally代码块进行资源释放
            System.out.println("无论是否发生异常finally都将执行");
        }
        System.out.println("我换行行了");
    }
}

Java中final、finally和finalize相似点和区别
  • 相似点:除了长得像没有任何相似

  • 区别点:

    • final是一个修饰主要用于修饰类、方法、常量,表示最终的无法修改的,

    • finally是捕获异常是所处理代码块,主要作用是无论异常是否发生都会执行代码块,可以用于保证长连接资源释放,

    • finalize是Object类中所提供一个方法,这个方法无需程序调用,调用这个方法是GC,当GC回收资源对象时会默认调用finalize进行收尾操作

13.3.5 自定义异常

Java中是提供了很多异常类类型,共开发者在程序中进行异常类型使用,但是Java中所定义的异常类型在某些时候,还是无法满足开发需求,根据自身开发业务逻辑自行定义异常,此时自定义异常就出现了

例如: 注册信息异常 —> RegisterException 胖了异常 —> PangExcetption

如果来定义自定义异常:

PS:在提供自定义异常时,你要明确原则是你要提供异常来使用【编译时异常还是运行时异常】

如果提供是自定义编译时异常: 只需要将自定义异常类继承与java.lang.Exception即可
如果提供是自定义运行时异常:只需要将自定义异常类继承与java.lang.RuntimeException即可
类中无需提供任何其他操作,只要仿照父类生成构造就可以了

//自定义的注册异常
public class RegisterException extends RuntimeException{
    //精简化只提供无参和一个参数为String message的有参构造方法即可
    //其他都可以提供
    public RegisterException() {
    }
    public RegisterException(String message) {
        super(message);
    }
    public RegisterException(String message, Throwable cause) {
        super(message, cause);
    }
    public RegisterException(Throwable cause) {
        super(cause);
    }
    public RegisterException(String message, Throwable cause, boolean
            enableSuppression, boolean writableStackTrace) {
        super(message, cause, enableSuppression, writableStackTrace);
    }
}
import java.util.Scanner;
public class Test3 {
    //在当前类中提供一个账号名数组
    private static String[] usernames = {"zhangsan","lisi","wangwu"};
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        System.out.println("请输入用户名:");
        String username = input.next();
        try {
            if (checkUserName(username)){
                System.out.println("注册成功");
            }
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }
    public static boolean checkUserName(String username){
        for(String name : usernames){
            if (name.equalsIgnoreCase(username)){
                throw new RegisterException("不好意思:"+username+"已经存在无法注
                        册");
            }
        }
        return true;
    }
}

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

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

相关文章

SpringCloud(12):Zuul路由网关

1 为什么需要服务网关 在分布式系统系统中,有商品、订单、用户、广告、支付等等一大批的服务,前端怎么调用呢?和每个服务一个个打交道?这显然是不可能的,这就需要有一个角色充当所有请求的入口,这个角色就是…

【C++】从0到1入门C++编程学习笔记 - 实战篇:通讯录管理系统

文章目录一、需求分析二、创建项目2.1 创建新项目2.1 添加文件三、菜单功能四、退出功能五、添加联系人5.1 设计联系人结构体5.2 设计通讯录结构体5.3 main 函数中创建通讯录5.4 封装添加联系人函数5.5 测试添加联系人功能六、显示联系人6.1 封装显示联系人函数6.2 测试显示联系…

STM32F103和AIR32F103的FreeRTOS中断优先级

关于 Arm Cortex M 系列内核的中断优先级 Cortex M 的中断和优先级 首先要区分开 中断 和 中断优先级 这是两个不同的东西, 不要搞混了 对于 Cortex-M0 和 Cortex-M0 内核, 除了系统内建中断外, 支持最多 32 个中断对于 Cortex-M3 内核, 除了 16 个内核中断外, 支持最多 240…

前端初学者的Ant Design Pro V6总结(上)

前端初学者的Ant Design Pro V6总结(上) 一、UI组件开发流程 () > {} 通用(异步)函数useEmotionCss 定义CSSuseModel获取全局状态useCallback 处理React合成事件JSX 拆分组件initiateState 中CurrentUser空值处理initiateSta…

8. 数字类型讲解

python3 数字类型的使用 1. 基础知识 Python 数字数据类型用于存储数值。 数据类型是不允许改变的,这就意味着如果改变数字数据类型的值,将重新分配内存空间。 可以使用del语句删除一些数字对象的引用。 del var1[,var2[,var3[....,varN]]]Python 支持三种不同的…

计算机视觉算法——基于深度学习的高精地图算法(HDMapNet / VectorMapNet / MapTR / VectorNet)

计算机视觉算法——基于深度学习的高精地图算法(HDMapNet / VectorMapNet / MapTR / VectorNet)计算机视觉算法——基于深度学习的高精地图算法(HDMapNet / VectorMapNet / MapTR / VectorNet)1. HDMapNet1.1 网络结构及特点1.1.1…

SAP SD 自定义销售订单审批状态

自定义销售订单审批状态 销售订单可以在其抬头或者项目中定义审批状态,一般在抬头定义的话就相当于针对整单的审批,可以实现多级审批,每级审批设置能进行何种操作,这里就需要在IMG中定义审批状态参数文件。 一、定义状态参数文件…

[精] MySQL和Oracle下Mybatis批量操作示例和获取影响行数介绍

手打不易,如果转摘,请注明出处! 注明原文:https://zhangxiaofan.blog.csdn.net/article/details/117933877 目录 前言 Mybatis 执行器 表结构定义 Mybatis批量新增 批量新增——Mysql写法 批量新增——Oracle写法 Mybatis批…

【甄选靶场】Vulnhub百个项目渗透——项目五十四:jarbas-1(类git反弹shell,计划任务提权)

Vulnhub百个项目渗透 Vulnhub百个项目渗透——项目五十四:jarbas-1(类git反弹shell,计划任务提权) 🔥系列专栏:Vulnhub百个项目渗透 🎉欢迎关注🔎点赞👍收藏⭐️留言📝 …

SpringMvc源码分析(四) 请求执行过程之执行MethodHandler

在上文SpringMvc源码分析(三)中我们分析了DispatcherServlet类中的doDispatcher方法, 并通过分析方法1和方法2了解了请求执行时是怎么获取MethodHandler链的,本文接上文继续分析方法3、方法4和方法5了解MethodHandler是如何执行的…

springboot rabbitmq 非阻塞重试机制实现

重试的应用场景 比如,系统之间同步数据,A系统发送数据给B系统,因为网络原因或者B系统正在重启,可能收不到信息,为了确保B能收到消息就得重试几次;经典的比如,微信支付回调 对后台通知交互时&am…

VScode远程连接Linux

文章目录一、下载安装二、使用三、连接四、基本操作五、VScode内置命令行六、推荐插件一、下载安装 下载的问题就不用多说了把,可能存在的问题就是下载的速度比较慢 前往官网进行下载:前往官网找到适合自己的版本: 但是由于官网是国外的&am…

DT-6_TTL-WiFi透传模块介绍

DT-6_TTL-WiFi透传模块简介TTL-WiFi模块基于ESP-M2WiFi 模块研发,引出串口TTL、EN、STATE等引脚。产品内置我司最新版本的串口透传固件可完成设备TTL 端口到WiFi/云的数据实时透传,具备低功耗控制,状态指示等功能。本模块可直接取代原有的有线…

【手写 Vue2.x 源码】第三十二篇 - diff算法-乱序比对

一,前言 上篇,diff算法-比对优化(下),主要涉及以下几个点: 介绍了儿子节点比较的流程介绍并实现了头头、尾尾、头尾、尾头4种特殊情况比对 本篇,继续介绍 diff算法-乱序比对 二,乱…

MATLAB | 全网最全边际图绘制模板(直方图、小提琴图、箱线图、雨云图、散点图... ...)

如标题所言,这应该是全网最全的边际图绘制模板,中心图有8种格式,边际图有11种格式,共计88种组合,另外模板中给了8款配色,我愿称其为888组合,只需要更换一下数据就能绘制出各种类型的边际图: 甚至…

中国机器视觉市场研究报告

目录 机器视觉行业概述机器视觉行业发展现状机器视觉行业典型企业分析机器视觉行业未来发展趋势 机器视觉行业概述 机器视觉定义 机器视觉(Machine Vision,MV)是人工智能正在快速发展的一个分支。根据美国制造工程师协会(SME&…

数字孪生虚拟电厂负荷控制系统可视化

随着国家“双碳”及“构建以新能源为主体的新型电力系统”等目标的提出,清洁化、数字化越来越成为电力系统面临的迫切需求,负控系统的发展对电力营销现代化建设具有重要的意义。负控管理系统是一个着眼于全面加强电力信息管理的,集负荷控制、…

Tips for Confluence Administrators: Part 2

Part 1中,我们谈到了 Confluence 自定义配置的案例,例如:如何禁用附件下载?如何将iFrame放入Confluence?如何使我的页面完全私有?如何防止空间管理员删除他们的空间?任何软件都有bug&#xff0c…

Minecraft 1.19.2 Forge模组开发 11.Mixin

我们本次使用Mixin在1.19.2中制作一个属于自己的不死图腾。 演示效果演示效果演示效果 什么是Mixin? 简单来说是通过注入一些我们的代码,达到对MC原版内容的修改。 详细内容可以参考Minecraft 17.1 Mixin 1.首先我们需要在开发包中引入mixin的依赖&a…

深度学习——双向循环神经网络(笔记)

双向循环神经网络: ①对于序列来讲,假设的目标是:给定观测的情况下(在时间序列的上下文或语言模型的上下文),对于下一个输出进行建模 ②对于序列模型来讲,可以从前往后看,也可以从…