【JavaSE篇】——异常(一万字让你了解异常的全方位知识)

目录

🎈什么是异常

🚩算术异常

🚩数组越界异常

🚩空指针异常

 🚩输入不匹配异常

🎈异常的体系结构

🎈异常的分类

🚩运行时异常(非受查异常)

🚩编译时异常(受查异常) 

🎈异常的处理

🚩防御式编程

🚩事后认错型 

🌈printStackTrace

🎈异常的捕获

🚩try-catch捕获并处理 

🎈异常的抛出

🚩异常声明throws

🎈finally

🎈异常的处理流程

🎈自定义异常类

🚩使用throw抛出自定义异常

🚩使用try..catch抛出自定义异常


🎈什么是异常

Java中,将程序执行过程中发生的不正常行为称为异常

🚩算术异常

ArithmeticException

public class Abnormal {public static void main(String[] args) {int a=10;int b=0;System.out.println(a/b);}
}Exception in thread "main" java.lang.ArithmeticException: / by zeroat Abnormal.main(Abnormal.java:5)
// 实际上JVM在执行到此处的时候,会new异常对象:new ArithmeticException("/ by zero");// 并且JVM将new的异常对象抛出,打印输出信息到控制台了。

🚩数组越界异常

ArrayIndexOutOfBoundsException

    public static void main(String[] args) {//数组越界异常int[] arr={0,1,2};System.out.println(arr[100]);}
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 100at Abnormal.main(Abnormal.java:5)

🚩空指针异常

NullPointerException

   public static void main(String[] args) {int[] arr=null;System.out.println(arr.length);}Exception in thread "main" java.lang.NullPointerExceptionat Abnormal.main(Abnormal.java:4)

 🚩输入不匹配异常

InputMismatchException

 

从上述过程中可以看到, java 中不同类型的异常,都有与其对应的类来进行描述
  • ArithmeticException   算术异常
  • ArrayIndexOutOfBoundsException  越界异常
  • NullPointerException   空指针异常
  • InputMismatchException    输入不匹配异常

🎈异常的体系结构

第一个图展示的只是部分的子类异常,第二个图是所有包含的。

从上图中可以看到:
  • 1. Throwable是异常体系的顶层类,其派生出两个重要的子类, Error 和 Exception
  • 2. Error指的是Java虚拟机无法解决的严重问题,比如:JVM的内部错误、资源耗尽等,典型代表: StackOverflowErrorOutOfMemoryError,一旦发生回力乏术。

  • 3. Exception异常产生后程序员可以通过代码进行处理,使程序继续执行。比如:感冒、发烧。我们平时所说的异常就是Exception

🎈异常的分类

异常可能在编译时发生,也有可能在程序运行时发生,根据发生时机不同,可以分为:

🚩运行时异常(非受查异常)

  • RuntimeException:运行时异常。(非受查异常)(在编写程序阶段程序员可以预先处理,也可以不管,都行。)

 运行时异常都是 RuntimeException 类及其子类异常,如 NullPointerException、IndexOutOfBoundsException 等,这些异常是不检查异常,程序中可以选择捕获处理,也可以不处理。这些异常一般由程序逻辑错误引起,程序应该从逻辑角度尽可能避免这类异常的发生。

 


🚩编译时异常(受查异常) 

  •  Exception的直接子类:编译时异常,(受查异常)(要求程序员在编写程序阶段必须预先对这些异常进行处理,如果不处理编译器报错,因此得名编译时异常。)。

编译时异常是指 RuntimeException 以外的异常,类型上都属于 Exception 类及其子类。从程序语法角度讲是必须进行处理的异常,如果不处理,程序就不能编译通过。如 IOException、ClassNotFoundException 等以及用户自定义的 Exception 异常,一般情况下不自定义检查异常。

class Person implements Cloneable{@Overrideprotected Object clone() throws CloneNotSupportedException {return super.clone();}
}
public class Abnormal {public static void main(String[] args) {Person person=new Person();Person person1=(Person) person.clone();}
}

我们按住alt加ctrl就显示了。 

class Person implements Cloneable{@Overrideprotected Object clone() throws CloneNotSupportedException {return super.clone();}
}
public class Abnormal {public static void main(String[] args) throws CloneNotSupportedException {Person person=new Person();Person person1=(Person) person.clone();}
}

注意:编译时出现的语法性错误,不能称之为异常。例如将 System.out.println 拼写错了 , 写成了system.out.println. 此时编译过程中就会出错 , 这是 "编译期" 出错。而运行时指的是程序已经编译通过得到 class 文件了 , 再由 JVM 执行过程中出现的错误 .

🎈异常的处理

🚩防御式编程

错误在代码中是客观存在的. 所以要让程序出现问题的时候快速通知程序猿. 

(1)LBYL 在操作之前就做充分的检查

private static int divide() {int a = 0, b = 0;Scanner scanner = new Scanner(System.in);a = scanner.nextInt();b = scanner.nextInt();if (b == 0) {System.out.println("除数为0");return 0;} else {return a / b;}}

缺点:正常流程和错误处理流程代码混在一起, 代码整体条理不清晰。


🚩事后认错型 

(2)EAFP 先操作遇到问题再处理

  • try…catch捕捉异常之后,后续代码可以执行(但是哪里出错误了那么跳到catch捕捉那里错误后面的代码就不执行了)。

处理异常的核心思想就是EAFP 


    public static void main(String[] args) {try {System.out.println(10/0);}catch (NullPointerException e){System.out.println("你这里出现算术异常了");}System.out.println("执行代码");}


异常处理的核心思想就是 EAFP
Java 中, 异常处理主要的 5 个关键字: throw try catch final throws

🌈printStackTrace

如果多个异常的处理方式是完全相同, 也可以写成这样: 

   public static void main7(String[] args) {try{int[] arr={1,2,3};// arr=null;// System.out.println(arr.length);System.out.println(arr[10]);}catch (NullPointerException|IndexOutOfBoundsException|ArithmeticException e){e.printStackTrace();}System.out.println("执行后续代码");
}

 我们可以 三者用|来拼接,然后调用printStackTrace方法进行检查哪一行出错误。


🎈异常的捕获

🚩try-catch捕获并处理 

我们看到上述俩者报错的方式,第一种我们try catch后续代码执行,第二种直接交给JVM处理直接终止程序。

有些同学问:一次抛出俩个或者多个异常怎么办?

—————这个是错误的,不会同时抛出俩个及以上的异常。

try…catch捕捉异常之后,后续代码可以执行(但是哪里出错误了那么跳到catch捕捉那里错误后面的代码就不执行了)。

 1.try中可能会抛出多个不同的异常对象,则必须用多个catch来捕获----即多种异常,多次捕获

    public static void main7(String[] args) {try{int[] arr={1,2,3};System.out.println(10/0);//算法异常arr=null;//空指针异常System.out.println(arr[10]);//越界异常} catch (NullPointerException e){e.printStackTrace();System.out.println("空指针异常");}catch (IndexOutOfBoundsException e){e.printStackTrace();System.out.println("栈溢出异常");}catch (ArithmeticException e){e.printStackTrace();System.out.println("你这里出现算法异常");}System.out.println("执行后续代码");
}

2. try块内抛出异常位置之后的代码将不会被执行

我们可以看到执行19行之后直接跳到catch()算术异常那去了。所以20行的空指针异常和21行的下标越界异常都没有执行直接跳过到catch捕捉了,所以我们不会出现俩个或者多个异常。

3. 如果抛出异常类型与catch时异常类型不匹配,即异常不会被成功捕获,也就不会被处理,继续往外抛,直到 JVM收到后中断程序----异常是按照类型来捕获的
public static void main(String[] args) {
try {
int[] array = {1,2,3};
System.out.println(array[3]); // 此处会抛出数组越界异常
}catch (NullPointerException e){ // 捕获时候捕获的是空指针异常--真正的异常无法被捕获到
e.printStackTrace();
}
System.out.println("后序代码");
}
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 3
at day20210917.ArrayOperator.main(ArrayOperator.java:24)
4.异常之间具有父子关系

5.一定是子类异常在前catch,父类异常在后catch,否则语法错误:

 

此时Exception是所有类的父类,那么 现在都交给他了,后面子类就没有意义了。所以我们需要让子类放在前面,如果子类没有,后面有个父类保底的。


🎈异常的抛出

在编写程序时,如果程序中出现错误,此时就需要将错误的信息告知给调用者,比如:参数检测。
Java 中,可以借助 throw 关键字,抛出一个指定的异常对象,将错误信息告知给调用者。具体语法如下:
throw new XXXException("异常产生的原因");
public class Abnormal {public static void test(int a){if(a==10){throw new NullPointerException();}}public static void main(String[] args) {test(10);}
}


还有一种是try..catch捕获

public class Abnormal {public static void test(int a){if(a==10){throw new NullPointerException();}}public static void main(String[] args) {try{test(10);}catch (NullPointerException e){e.printStackTrace();System.out.println("你这里出现异常了");}}
}


  • 1. throw必须写在方法体内部
  • 2. 抛出的对象必须是Exception 或者 Exception 的子类对象

受查异常就是编译异常,默认是编译异常。

  • 3. 如果抛出的是 RunTimeException 或者 RunTimeException 的子类,则可以不用处理,直接交给JVM来处理

  • 4. 如果抛出的是编译时异常,用户必须处理,否则无法通过编译

🚩异常声明throws

处在方法声明时参数列表之后,当方法中抛出编译时异常,用户不想处理该异常,此时就可以借助throws将异常抛给方法的调用者来处理。即当前方法不处理异常,提醒方法的调用者处理异常

语法格式:
修饰符 返回值类型 方法名(参数列表) throws 异常类型1,异常类型2...{
}public static void test3(int a) throws CloneNotSupportedException,OutOfMemoryError,StackOverflowError 

 

注意事项
1. throws必须跟在方法的参数列表之后
2. 声明的异常必须是 Exception 或者 Exception 的子类
3. 方法内部如果抛出了多个异常,throws之后必须跟多个异常类型,之间用逗号隔开,如果抛出多个异常类型具有父子关系,直接声明父类即可。
public class Config {
File file;
// public void OpenConfig(String filename) throws IOException,FileNotFoundException{
// FileNotFoundException 继承自 IOException
public void OpenConfig(String filename) throws IOException{if(filename.endsWith(".ini")){throw new IOException("文件不是.ini文件");}if(filename.equals("config.ini")){throw new FileNotFoundException("配置文件名字不对");}// 打开文件
}public void readConfig(){}
}

4. 调用声明抛出异常的方法时,调用者必须对该异常进行处理,或者继续使用throws抛出


🎈finally

在写程序时, 有些特定的代码,不论程序是否发生异常,都需要执行,比如程序中打开的资源 :网络连接、数据库 连接、IO 流等, 在程序正常或者异常退出时,必须要对资源进进行回收 。另外,因为 异常会引发程序的跳转,可能 导致有些语句执行不到 finally 就是用来解决这个问题的。
语法格式:
try{
// 可能会发生异常的代码
}catch(异常类型 e){
// 对捕获到的异常进行处理
}finally{
// 此处的语句无论是否发生异常,都会被执行到
}
// 如果没有抛出异常,或者异常被捕获处理了,这里的代码也会执行

就拿scanner来做比较吧,我们System.in进行输入,然后scanner需要一个scanner.close()进行关闭输入。

    public static void main(String[] args) {Scanner scanner=new Scanner(System.in);try {int n=scanner.nextInt();}catch (InputMismatchException e){e.printStackTrace();System.out.println("输入的内容和类型不匹配");}finally {System.out.println("执行了finally代码,finally一般是用来关于资源的");scanner.close();}System.out.println("如果没有抛出异常,或者异常被处理了,try-catch后的代码也会执行");}

如果不想写scanner.close()我们需要再try里面声明。

    public static void main(String[] args) {try( Scanner scanner=new Scanner(System.in)) {int n=scanner.nextInt();}catch (InputMismatchException e){e.printStackTrace();System.out.println("输入的内容和类型不匹配");}finally {System.out.println("执行了finally代码,finally一般是用来关于资源的");//  scanner.close();}System.out.println("如果没有抛出异常,或者异常被处理了,try-catch后的代码也会执行");}


问题:既然 finally 和 try-catch-finally 后的代码都会执行,那为什么还要有finally呢?
public static  int getDate(){Scanner sc=null;try {sc=new Scanner(System.in);int n=sc.nextInt();return n;}catch (InputMismatchException e){e.printStackTrace();}finally {System.out.println("执行了finally");}System.out.println("try-catch-finally后面的代码");if(sc!=null){sc.close();}return 0;}public static void main(String[] args) {int date=getDate();System.out.println(date);}

此时我们可以证明肯定是会执行finally的代码。所以我们给sc.close()放到finally。上述程序,如果正常输入,成功接收输入后程序就返回了,try-catch-finally之后的代码根本就没有执行,即输入流就没有被释放,造成资源泄漏。所以给sc.close()写到finally中。


注意: finally 中的代码一定会执行的,一般在 finally 中进行一些资源清理的扫尾工作
// 下面程序输出什么?
public static void main(String[] args) {System.out.println(func());
}
public static int func() {
try {return 10;
} finally {return 20;}
}
A: 10 B: 20 C: 30 D: 编译失败

我们上面知道肯定会执行finally,所以结果是20.

finally 执行的时机是在方法返回之前 (try 或者 catch 中如果有 return 会在这个 return 之前执行 finally). 但是如果finally 中也存在 return 语句 , 那么就会执行 finally 中的 return, 从而不会执行到 try 中原有的 return.
一般我们不建议在 finally 中写 return ( 被编译器当做一个警告 )

🎈异常的处理流程

1.如果本方法中没有合适的处理异常的方式, 就会沿着调用栈向上传递
    public static void func1() {int[] arr = {1, 2, 3};System.out.println(arr[100]);}public static void main(String[] args) {try {func1();} catch (ArrayIndexOutOfBoundsException e) {e.printStackTrace();}System.out.println("after try catch");}

2.如果向上一直传递都没有合适的方法处理异常, 最终就会交给 JVM 处理, 程序就会异常终止(和我们最开始未使用 try catch 时是一样的).
   public static void func2() {int[] arr = {1, 2, 3};System.out.println(arr[100]);}public static void main(String[] args) {func();System.out.println("after try catch");}


异常处理流程总结
  • 程序先执行 try 中的代码
  • 如果 try 中的代码出现异常, 就会结束 try 中的代码, 看和 catch 中的异常类型是否匹配.
  • 如果找到匹配的异常类型, 就会执行 catch 中的代码
  • 如果没有找到匹配的异常类型, 就会将异常向上传递到上层调用者.
  • 无论是否找到匹配的异常类型, finally 中的代码都会被执行到(在该方法结束之前执行).
  • 如果上层调用者也没有处理的了异常, 就继续向上传递.
  • 一直到 main 方法也没有合适的代码处理异常, 就会交给 JVM 来进行处理, 此时程序就会异常终止.

🎈自定义异常类

Java 中虽然已经内置了丰富的异常类 , 但是并不能完全表示实际开发中所遇到的一些异常,此时就需要维护符合我们实际情况的异常结构.
例如 , 我们实现一个用户登陆功能 .
class Login{private String name="chenle";private int age=20;public  void loginInfo(String name, int age){if(!this.name.equals(name)){System.out.println("用户名错误");return;}if(this.age!=age){System.out.println("年龄错误");return;}}
}
public class Abnormal {public static void main(String[] args) {Login login=new Login();login.loginInfo("chenle1",201);}
}

我们代码输出“用户名错误”。我们如果用异常来写呢?因为再异常中没有密码错误异常和年龄错误异常,所以这时候我们需要自定义异常。

我们对照空指针异常的源代码继承的是RuntimeException,里面有一段定义和构造。

1. 自定义异常类,然后继承自Exception 或者 RunTimeException
2. 实现一个带有String类型参数的构造方法,参数含义:出现异常的原因

我们创建一个类叫 UserNameErrorException和ageErrorException继承运行异常类,然后写上俩个构成重载的构造方法。

public class UserNameErrorException extends RuntimeException{public UserNameErrorException() {super();}public UserNameErrorException(String s){super(s);}
}public class ageErrorException extends RuntimeException{public ageErrorException() {super();}public ageErrorException(String s){super(s);}
}

🚩使用throw抛出自定义异常

class Login{private String name="chenle";private int age=20;public  void loginInfo(String name, int age){if(!this.name.equals(name)){throw new UserNameErrorException("用户名错误");}if(this.age!=age){throw new ageErrorException("年龄错误");}}
}
public class Abnormal {public static void main(String[] args) {Login login=new Login();login.loginInfo("chenle1",201);}
}

由于上述俩个是个单独的执行,再实际的开发中,我们需要将俩者都放在一起,这时候用到的是try..catch。


🚩使用try..catch抛出自定义异常

class Login{private String name="chenle";private int age=20;public  void loginInfo(String name, int age){try{if(!this.name.equals(name)){throw new UserNameErrorException("用户名错误");}if(this.age!=age){throw new ageErrorException("年龄错误");}System.out.println("登录成功");}catch (UserNameErrorException e){e.printStackTrace();}catch (ageErrorException e){e.printStackTrace();}}
}
public class Abnormal {public static void main(String[] args) {Login login=new Login();login.loginInfo("chenle1",201);}
}


注意事项
  • 自定义异常通常会继承自 Exception 或者 RuntimeException
  • 继承自 Exception 的异常默认是受查异常
  • 继承自 RuntimeException 的异常默认是非受查异常

 新的开始了。

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

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

相关文章

解锁Spring Boot中的设计模式—05.策略模式:探索【策略模式】的奥秘与应用实践!

1.策略者工厂模式(Map版本) 1.需求背景 假设有一个销售系统,需要根据不同的促销活动对商品进行打折或者其他形式的优惠。这些促销活动可以是针对不同商品类别的,比如男装、女装等。 2.需求实现 活动策略接口:定义了…

iPhone 16 组件泄露 揭示了新的相机设计

iPhone 16 的发布似乎已经等了很长一段时间,但下一个苹果旗舰系列可能会在短短 7 个月内与我们见面——而新的组件泄漏让我们对可能即将到来的重新设计有了一些了解。后置摄像头模块。 爆料者 Majin Bu(来自 MacRumors)获得的示意图显示&…

迅为3A5000_7A2000开发板龙芯自主指令系统支持PCIE3.0、USB3.0、SATA3.0、HDMI、VGA等

性能强 采用全国产龙芯3A5000处理器,基于龙芯自主指令系统 (LoongArch)的LA464微结构,并进一步提升频率,降低功耗,优化性能。 桥片 采用龙芯 7A2000,支持PCIE 3.0、USB 3.0和 SATA 3.0.显示接口2 路、HDMI 和1路 VGA…

Doris ——SQL原理解析

目录 前言 一、Doris简介 二、SQL解析简介 2.1 词法分析 2.2 语法分析 2.3 逻辑计划 2.4 物理计划 三、Doris SQL解析的总体架构 四、Parse阶段 五、Analyze阶段 六、SinglePlan阶段(生成单机逻辑Plan阶段) 七、DistributedPlan计划&#xf…

【大厂AI课学习笔记】【2.1 人工智能项目开发规划与目标】(5)数据管理

今天学习了数据管理,以及数据管理和数据治理的区别和联系。 数据管理:利用计算机硬件和软件技术对数据进行有效的收集、存储、处理和应用的过程其目的在于充分有效地发挥数据的作用。 实现数据有效管理的关键是数据组织。 数据管理和数据治理的区别&am…

【开源】SpringBoot框架开发智能教学资源库系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 课程档案模块2.3 课程资源模块2.4 课程作业模块2.5 课程评价模块 三、系统设计3.1 用例设计3.2 数据库设计3.2.1 课程档案表3.2.2 课程资源表3.2.3 课程作业表3.2.4 课程评价表 四、系统展示五、核心代…

微服务—DSL基础语法与RestClient操作

本博客为个人学习笔记,学习网站:黑马程序员SpringCloud 2021教程 目录 DSL语法 索引库操作 mapping属性 创建索引库 字段拷贝 查询、删除、修改索引库 文档操作 新增文档 查询、删除文档 修改文档 全量修改 增量修改 DSL文档语法小结 Rest…

服务流控(Sentinel)

引入依赖 <!-- 必须的 --> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId> </dependency><!-- sentinel 核心库 --> <dependency><groupId>com.ali…

Spring 用法学习总结(四)之 JdbcTemplate 连接数据库

&#x1f409;目录 9 JdbcTemplate 9 JdbcTemplate Spring 框架对 JDBC 进行了封装&#xff0c;使用 JdbcTemplate 方便实现对数据库操作 相关包&#xff1a; 百度网盘链接https://pan.baidu.com/s/1Gw1l6VKc-p4gdqDyD626cg?pwd6666 创建properties配置文件 &#x1f4a5;注意…

如何使用python 挑战将ai生成的概念图制作成2d游戏

要使用Python将AI生成的概念图制作成2D游戏&#xff0c;你可以遵循以下步骤&#xff1a; 生成概念图&#xff1a; 使用AI图像生成工具&#xff08;如DALL-E、DeepArt等&#xff09;来创建你的游戏概念图。保存生成的图像文件&#xff0c;通常为PNG或JPEG格式。 选择游戏引擎&a…

STM32的三种下载方式

结果jlink&#xff0c;串口&#xff0c;stlink方式都没有问题&#xff0c;是当时缩减代码&#xff0c;看真正起作用的代码段有哪些&#xff0c;就把GPIO初始化中 /*开启GPIO外部时钟*/RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA, ENABLE); 把开启外部时钟的代码注释掉了。…

vue-路由(六)

阅读文章你可以收获什么&#xff1f; 1 明白什么是单页应用 2 知道vue中的路由是什么 3 知道如何使用vueRouter这个路由插件 4 知道如何如何封装路由组件 5 知道vue中的声明式导航router-link的用法 6 知道vue中的编程式导航的使用 7 知道声明式导航和编程式导航式如何传…

2024.2.15 模拟实现 RabbitMQ —— 消息持久化

目录 引言 约定存储方式 消息序列化 重点理解 针对 MessageFileManager 单元测试 小结 统一硬盘操作​​​​​​​ 引言 问题&#xff1a; 关于 Message&#xff08;消息&#xff09;为啥在硬盘上存储&#xff1f; 回答&#xff1a; 消息操作并不涉及到复杂的增删查改消…

MIT-BEVFusion系列八--onnx导出2 spconv network网络导出

这里写目录标题 export-scn.py加载模型设置每层的精度属性初始化输入参数导出模型model.encoder_layers 设置初始化参数设置 indice_key 属性更改 lidar backbone 的 forward更改lidar网络内各个层的forward带参数装饰器&#xff0c;钩子函数代码使用装饰器修改forward举例 跟踪…

Codeforces Round 926 (Div. 2)

C:Sasha and the Casino 类似于倍投法&#xff0c;就是在一赔一的情况下,第一次压一块钱,每输一次就押注上一次两倍的金额. 假如资金无限的话,这种方法赢的期望为无穷大.原理类似于二进制&#xff0c;不论你输再多次,只要赢一次总额就增加了1.比如 15 二进制1111&#xff0c;…

【嵌入式】校招信息表(持续更新)

相关文章 写一份让HR过目不忘的简历 嵌入式校招信息表 一、校招信息表二、注意事项三、最后 一、校招信息表 二、注意事项 三、最后 【校招】如何写出HR最喜欢的简历&#xff0c;一个视频讲清楚

CTFshow web(php文件上传155-158)

web155 老样子&#xff0c;还是那个后端检测。 知识点&#xff1a; auto_append_file 是 PHP 配置选项之一&#xff0c;在 PHP 脚本执行结束后自动追加执行指定的文件。 当 auto_append_file 配置被设置为一个文件路径时&#xff0c;PHP 将在执行完脚本文件的所有代码后&…

如何减少HTTP请求次数

资料来源 : 小林coding 小林官方网站 : 小林coding (xiaolincoding.com) 如何减少HTTP请求次数? 减少 HTTP 请求次数自然也就提升了 HTTP 性能&#xff0c;可以从这 3 个方面入手: 减少重定向请求次数合并请求延迟发送请求 减少重定向请求次数 我们先来看看什么是重定向请…

第6个-滚动动画

Day 6 - Scroll Animation 1. 演示效果 2. 分析思路 布局 所有的内容进行水平垂直居中&#xff0c;可以使用**margin:0 auto;&#xff0c;也可以使用flex**布局&#xff1a; body {background-color: #efedd6;display: flex;flex-direction: column;justify-content: center…

【C++】C++11上

C11上 1.C11简介2.统一的列表初始化2.1 {} 初始化2.2 initializer_list 3.变量类型推导3.1auto3.2decltype3.3nullptr 4.范围for循环5.final与override6.智能指针7. STL中一些变化8.右值引用和移动语义8.1左值引用和右值引用8.2左值引用与右值引用比较8.3右值引用使用场景和意义…