去年四月份大一下半学期正式开始学习Java,一路从java基础、数据库、jdbc、javaweb、ssm以及Springboot,其中也学习了一段时间数据结构。html
在javaweb期间作了图书商城项目、ssm阶段作了权限管理项目,springboot学了以后手痒去b站看视频作了个我的博客项目(已部署到服务器,正在备案中)。期间也不断进行作笔记,总结,可是越学到后面越感受有点虚,以为本身基础还有欠缺。java
以后一段时间我会从新回顾java基础、学习一些设计模式,学习多线程并发之类,以及接触一些jvm的相关知识,越学到后面越会感受到基础的重要性,以后也会以博客形式输出学习的内容。web
如今整理的java知识基础点是在以前学习尚硅谷java课程的笔记基础之上加工汇总,部分图片会引用尚硅谷或网络上搜集或本身画,在从新回顾的过程当中也在不断进行查漏补缺,尽量将以前困惑的点都解决,让本身更上一层楼吧。spring
博客目录索引:博客目录索引(持续更新)数据库
概述说明编程
异常分类:编译时异常与运行时异常设计模式
这里要讲的异常指的是运行时异常,其分为两类异常事件:数组
Error
:Java虚拟机没法解决的严重问题。例如:JVM系统内部错误、资源耗尽等严重状况。好比:StackOverflowError(栈溢出)和OOM(内存溢出)。Exception
:其余因编程错误或偶然的外在因素致使的通常性问题,可使用针对性的代码进行处理,例如空指针访问、试图读取不存在文件、网络链接中断、数组角标越界问题。Error表示不可控异常通常不编写针对性的代码进行处理;而对于Exception这类异常,咱们能够编写针对性的代码进行处理。springboot
Error的实例服务器
看Error的两个实例:栈溢出与内存溢出
package com.mjj.pro7; public class Test1 { public static void main(String[] args) { //1.栈溢出,无限压栈 报错 java.lang.StackOverflowError //main(args); //2.堆溢出,建立占用超过初始jvm使用的内存,java.lang.OutOfMemoryError: Integer[] arr = new Integer[1024*1024*1024]; } }
针对于这Error的状况,咱们不对其进行针对性处理。
非受检异常:例如RuntimeException在默认状况下会获得自动处理,能够捕获RuntimeException异常,但对于本身的封装RuntimeException的异常,一部分仍是须要进行手动抛出。
受检异常:Java编译器要求程序必须捕获或声明抛出这种异常。
表示运行时异常,接下来进行实例举例
import org.junit.Test; public class ExceptionTest { //NullPointerException @Test public void test1(){ //例1 // int[] arr = null; // System.out.println(arr[3]); //例2 String str = null; System.out.println(str.charAt(0)); } }
//IndexOutOfBoundsException @Test public void test2(){ //第一种 ArraryIndexOutOfBoundsException // int[] arr = new int[10]; // System.out.println(arr[10]); //第二种 StringIndexOutOfBoundsException String arr = "123"; System.out.println(arr.charAt(3)); }
//ClassCastException 类型转换问题 @Test public void test3(){ Object obj = new Date(); String str = (String)obj; }
//NumberFormatException 数值类型转换 @Test public void test4(){ String str = "123"; //是经过的 String str1 = "abc"; int num = Integer.parseInt(str1); }
//InputMismatchException 输入不匹配 @Test public void test5(){ Scanner sca = new Scanner(System.in); int num = sca.nextInt(); //当输入abc时会报这个错误 sca.close(); }
//ArithmeticException 算术异常 @Test public void test6(){ System.out.println(5/0);//java.lang.ArithmeticException: / by zero }
问:对于上面异常体系结构中不受检异常指的是咱们不进行异常处理系统也会自行捕捉到异常,而且输出异常信息。那么咱们处理异常与不处理异常的区别在哪以及为何要进行异常处理?
看一下是否进行异常处理的区别
①不进行异常处理
public class Main { public static void main(String[] args){ String str = "abc"; int number; //有异常的语句 int i = Integer.parseInt(str); System.out.println(123); } }
能够看到一旦出现异常程序直接中止,后面的语句再也不执行!!!
②进行异常处理
public class Main { public static void main(String[] args){ String str = "abc"; int number; //进行异常处理 try { int i = Integer.parseInt(str); } catch (NumberFormatException e) { e.printStackTrace(); } System.out.println(123); } }
咱们能够看到程序完整的执行了下来后面的语句也进行了执行,这里咱们是对异常状况进行打印输出!!!
对异常的处理会有两个过程:抛、抓
try-catch-finally
、throws
语法:
try{ //可能出现异常的代码 }catch(异常类型1 变量名1){ //处理异常的方式1 }catch(异常类型2 变量名2){ //处理异常的方式2 } ... finally{ //必定会执行的代码 }
e.getMessage()
:获取异常的简略信息。e.printStackTrace()
:比较经常使用,打印完整的堆栈状况,会显示指定的出错位置。注意点5中的实例演示:
public class Main { public static void main(String[] args){ String str = "abc"; int number; try { int i = Integer.parseInt(str); } catch (NumberFormatException e) { //e.printStackTrace(); //详细堆栈错误信息 System.out.println(e.getMessage());//简略信息 } } }
注意点1中状况举例:
public class Main { public static void main(String[] args){ try{ int a=10; int b=0; System.out.println(a/b); }catch(ArithmeticException e){ int[] a = new int[10]; //这里有数组越界异常 System.out.println(a[10]); } finally{ System.out.println("执行finally语句"); } System.out.println("长路哥哥"); } }
注意点2中举例:
public class Main { public static void main(String[] args){ System.out.println(Main.method()); System.out.println(123456); } public static int method(){ try{ System.out.println(10/0); }catch(ArithmeticException e){ int[] a = new int[10]; //这里有数组越界异常 System.out.println(a[10]); return 2; } finally{ return 3; } } }
能够看到结果没有出现异常,说明返回的是finally中的。
缘由:在方法中catch出现异常了,会直接先去执行finally中内容,这里finally中是返回值,那么当catch异常处理前方法已经结束了,因此没有报异常出来!!!
例如数据库链接、输入输出流,网络编程Socket等资源,JVM是不能自动的回收的,咱们须要本身手动的进行资源的释放,此时的资源释放,就须要声明在finally中。
下面例子是演示输入输出流的关闭:
import java.io.*; public class Main { public static void main(String[] args){ File file = new File("hello.txt"); FileInputStream fis = null; try { fis = new FileInputStream(file); int read = fis.read(); while(read != -1){ System.out.println((char)read); read = fis.read(); } } catch (IOException e) { e.printStackTrace(); }finally { //fis放在这里进行关闭资源 再使用一个try-catch是由于IOException是受检型的必须声明 try { if(fis != null) fis.close(); } catch (IOException e) { e.printStackTrace(); } } } }
在项目工程目录下添加hello.txt文件后执行
使用于main()中:
try-catch:try异常,catch无异常进行处理,执行try-catch结构外的。
try-catch:try异常,catch异常,直接结束程序(打印异常)。
try-catch-finally:try异常,执行指定catch中,无异常会先执行完catch内容,接着执行finally中内容,而后执行try-catch之外内容。
try-catch-finally:try异常,执行指定catch中如果有异常会先执行finally内容,接着程序结束(打印异常)。
调用单独方法中:
try-catch:try异常,catch无异常,正常执行后序程序。
try-catch:try异常,catch异常,程序直接结束(打印异常)。
try-catch-finally:catch与finally中都有返回值,如果catch中出现异常,会先去找finally,以后直接结束方法,此时异常也不会打印。
无try-catch结构捕捉异常,也无throws抛出,对于出现非受检查的异常系统会自动抛出。
总结总结:catch中无异常,执行完catch后执行finally以及try-catch结构以外的;catch中如果出现异常会先去执行finally中内容,接着程序直接中止。
语法:throws 异常类
//例如 public void method()throws RuntimeException{ }
写在方法的声明处,指明此方法执行时可能会抛出的异常。一旦方法体执行时,出现异常,仍会在异常代码处生成一个异常类的对象,若此对象知足throws的异常就会抛出,在方法中出现异常代码后续的代码就不会执行。
与try-catch-finally比较:
try-catch-finally
:真正将异常处理掉。throws
:将异常抛给方法的调用者,并无真正将异常处理掉。实例1:throws声明可能会抛出的异常(表示了一种规范),方法中出现异常则会向上传递:
import java.io.*; public class Main { public static void main(String[] args){ try { method1(); } catch (RuntimeException e) { System.out.println("捕捉到方法中的异常"); } } public static void method1() throws RuntimeException { method2(); } public static void method2 () throws RuntimeException{ System.out.println(5/0); } }
其实就算我两个方法都不添加throws RuntimeException,最终使用try-catch也是可以接收到的,那为何要使用thorows声明勒?也能够算是一种规范吧,声明则指明其方法可能会出现的异常,好让调用方法者知道捕捉异常时使用什么类型捕捉!!!不声明的话使用try-catch结构中catch默认会是Exception。
对于重写方法throws的规则:
实例以下:
class SuperClass{ public void method()throws IOException{ } } class SubClass extends SuperClass{ //继承SuperClass @Override public void method() throws FileNotFoundException { //子类重写方法异常应当小于等于父类的异常 } }
Java7 build 105版开始,Java7的编译器和运行环境支持新的 try-with-resources 语句,称为 ARM 块(Automatic Resource Management) ,自动资源管理。
语法如:try块退出时,会自动调用res.close()方法,关闭资源
try(Resource res = xxx)//可指定多个资源 { work with res }
这相比咱们以前在finally中一个个手动关闭资源好的多。
咱们看一下二者对比:
//之前try{}catch{}: FileInputStream fis = null; FileOutputStream fos = null; try { //目标图片1234.jpg fis = new FileInputStream(new File("1234.jpg")); //复制地址 fos = new FileOutputStream(new File("图片.jpg")); .... } catch (IOException e) { e.printStackTrace(); }finally { if(fis != null){ try { fis.close(); } catch (IOException e) { e.printStackTrace(); } } if(fos != null){ try { fos.close(); } catch (IOException e) { e.printStackTrace(); } } } //如今的try(){} try ( FileInputStream fis = new FileInputStream(new File("1234.jpg")); FileOutputStream fos = new FileOutputStream(new File("图片.jpg")); ){ .... } catch (IOException e) { e.printStackTrace(); }
省去了大量的语句,舒服!!!
介绍一下异常对象的产生:①系统在出现异常时自动生成异常对象②手动生成一个异常对象,例如throw new Exception()
只要是使用了throw,就必定表示抛出了一个异常,而throws只是用于声明可能抛出的异常便于调用其方法的人作出相应的异常处理!!
实例:手动抛出异常,并使用throws声明该方法可能会有什么异常
public class Main { public static void main(String[] args){ try { Main.method(""); } catch (RuntimeException e) { System.out.println(e.getMessage()); } } public static void method(String str)throws RuntimeException{ if(!"".equals(str)){ System.out.println(str); }else { throw new RuntimeException("str不能为空"); } } }
首先问一下为何要自定义异常类勒?有几点缘由,例如设置多个本身定义的异常类,仅仅捕获其本身所关心的异常类,并知道如何处理;根据本身的需求出现异常的时候来去作特殊的处理;异常分类,业务中不一样场景抛出不一样异常,便于统一捕获并根据类型作进一步处理
对于自定义异常类有几点规范以下:
serialVersionUID
,用来标识本身定义的异常类自定义异常:包含最基本的几个部分
class MyException extends RuntimeException{ //须要一个UID来表示本身的自定义异常类 static final long serialVersionUID = -7034897190745766959L; public MyException(){ } //想要有自定义异常描述,就须要有一个有参构造 public MyException(String msg){ super(msg); } }
//测试上面的自定义异常 public class Main { public static void main(String[] args){ try { Main.method(""); } catch (MyException e) { System.out.println(e.getMessage()); } } //测试使用 public static void method(String str)throws MyException{ if(!"".equals(str)){ System.out.println(str); }else { throw new MyException("自定义异常描述:str不许为空"); } } }
[1]. Java受检异常和非受检异常
[3]. Java 中的异常和处理详解
[5]. Java:为何要有自定义异常?
[6]. Java自定义异常(优雅的处理异常) 实际应用配合枚举
[7]. java try(){}catch(){}自动资源释放
我是长路,感谢你的阅读,若有问题请指出,我会听取建议并进行修正。 欢迎关注个人公众号:长路Java,其中会包含软件安装等其余一些资料,包含一些视频教程以及学习路径分享。 学习讨论qq群:891507813 咱们能够一块儿探讨学习 注明:转载可,须要附带上文章连接