day05 【API、异常】
今日内容介绍
java
Math类
BigInteger类
BigDecimal类
基本类型包装类
异常
第一章 Math 类
1.1 Math 类的介绍【重点学会怎么找到并使用】
java
/*
java.lang.Math类: 用于数学运算的工具类
特点:
1.成员都使用static修饰
2.构造方法private修饰
静态成员:
public static final double PI: 常量,代表圆周率
public static int abs(int a): 返回参数的绝对值
public static double ceil(double a): 返回大于或等于参数的最小double值,等于一个整数
public static double floor(double a): 返回小于或等于参数的最大double值,等于一个整数
public static int round(float a): 按照四舍五入返回最接近参数的int
public static double pow(double a, double b): 计算a的b次方
注意:
以上方法中必须掌握ceil方法
*/
1.2 Math 类的使用【重点】
java
package com.itheima.demo;
public class MathDemo {
public static void main(String[] args) {
/**
* Math类 是数学类
* 里面封装了跟数学运算相关的方法。
* 也就是说如果我们程序中遇到了一些数学运算,那么我们可以直接调用Math的功能即可,就不需要我们人为的是实现了。
*
* 这种类在实际开发应用场景在哪里呢?
* 比如:
* 计算商品的时候,如果给商品打折比如88折,得到的结果可能是不是有好多位数,需要四舍五入。
* 猿辅导教育---初中生数学辅导,习题,计算三角函数的--调用方法计算出来。
*/
/**
* public static int abs(int a) 计算绝对值
* public static double ceil(double a) 向上取整
* public static double floor(double a) 向下取整
* public static int round(float a) 四舍五入
*/
System.out.println(Math.abs(-100));//100
System.out.println(Math.abs(100));//100
//向上取整 --找到大于等于 其的 整数值(小数形式)
System.out.println(Math.ceil(3.14));//4.0
System.out.println(Math.ceil(-3.14));//-3.0
//向下取整 -- 找到小于等于 其的 整数值(小数形式)
System.out.println(Math.floor(3.14));//3
System.out.println(Math.floor(-3.14));//-4
// 四舍五入
System.out.println(Math.round(3.14));// 四舍五入成整数
}
}
第二章 BigInteger 类
2.1 大数运算介绍
java
/*
1.基本类型整数的取值范围?
byte 1个字节 -128到127
short 2个字节 正负3万多
int 4个字节 正负21亿
long 8个字节 大概19位数字
2.基本类型整数取值范围最大的就是long类型, 如果整数的范围超过了long类型,怎么办呢?
解决方案: 大整数
java.math.BigInteger类: 代表超级大的整数,不可变的任意精度的整数。
3.基本类型小数的取值范围?
float 4个字节
double 8个字节
4.基本类型小数取值范围最大的就是double类型, 如果小数的范围超过了double类型,怎么办呢?
解决方案: 大小数
java.math.BigDecimal类: 代表超级大的小数,不可变的、任意精度的小数。
5.注意:
如果数据的取值范围超出了数字的最大范围,此时这样的数字称为大数
java.math.BigInteger类: 代表超级大的整数,不可变的任意精度的整数。
java.math.BigDecimal类: 代表超级大的小数,不可变的、任意精度的小数。
*/
2.2 BigInteger 类的使用
大整数使用套路
- 把数据先封装到大整数对象中
- 跟另外一个大整数 进行加减乘除
java
/*
BigInteger类的使用
java.math.BigInteger类: 代表超级大的整数,不可变的任意精度的整数。
1.构造方法:
public BigInteger(String val):
作用: 把构造方法参数String类型的val,转换成BigInteger类的对象
参数: 必须是String类型的数字,内部不能出现非数字内容
2.常用方法:
数学运算中最常用的就是+,-,*,/,所以对于BigInteger类提供了对应的方法
public BigInteger add(BigInteger val):
完成数学中的加法运算,
返回其值为 (this(调用add方法的BigInteger对象) + val(调用add方法时传递的参数BigInteger对象)) 的 BigInteger。
public BigInteger subtract(BigInteger val):
完成数学中的减法运算,
返回其值为 (this(调用add方法的BigInteger对象) - val(调用add方法时传递的参数BigInteger对象)) 的 BigInteger。
public BigInteger multiply(BigInteger val):
完成数学中的乘法运算,
返回其值为 (this(调用add方法的BigInteger对象) * val(调用add方法时传递的参数BigInteger对象)) 的 BigInteger。
public BigInteger divide(BigInteger val):
完成数学中的除法运算,
返回其值为 (this(调用add方法的BigInteger对象) / val(调用add方法时传递的参数BigInteger对象)) 的 BigInteger。
*/
java
package com.itheima.math01;
import java.math.BigInteger;
public class BigIntegerDemo {
public static void main(String[] args) {
// 大整数的使用 表示任意长度的 整数 不受个数限制
// int i1 = 2222222222;
// int i2 = 1123444422;
// System.out.println(i1+i2);
//构造 BigInteger(String value)
BigInteger a = new BigInteger("2222222222");
BigInteger b = new BigInteger("1111111111");
//大整数怎么计算
//调用方法
System.out.println("a+b:"+a.add(b));
System.out.println("a-b:"+a.subtract(b));
System.out.println("a*b:"+a.multiply(b));
System.out.println("a/b:"+a.divide(b));
}
}
2.3 浮点数的不精确性
java
/*
使用double完成加减乘除运算
问题: 出现损失精度的问题
不允许: 钱的问题
解决方案: 使用java.math.BigDecimal类
*/
public class Demo04DoubleProblem {
public static void main(String[] args) {
double d1 = 0.03;
double d2 = 0.02;
System.out.println(d1 + d2);
System.out.println(d1 - d2);
System.out.println(d1 * d2);
System.out.println(d1 / d2);
}
}
第三章 BigDecimal 类 银行要用
3.1 BigDecimal 类的介绍
java
/*
BigInteger类的使用
java.math.BigDecimal类: 代表超级大的小数,不可变的任意精度的小数。
1.构造方法:
public BigDecimal(String val):
作用: 把构造方法参数String类型的val,转换成BigDecimal类的对象
参数: 必须是String类型的数字,内部不能出现非数字内容
2.常用方法:
数学运算中最常用的就是+,-,*,/,所以对于BigDecimal类提供了对应的方法
对于+,-,*这些运算和BigInteger是一样的,就不再演示了
但是对于 除法 运算,可能会出现 无限循环/无限不循环的结果
然而BigDecimal是用来完成超级精确的数学运算,这样就导致
BigDecimal不知道到底给你什么样的结果?
解决方案:
(1)告诉它保留多少位小数
(2)如何保留小数
public BigDecimal divide(BigDecimal divisor, int scale, int roundingMode):
按照方法参数指定的保留位数以及保留方式做除法运算
参数:
int scale: 要保留几位小数
int roundingMode: 如何保留小数
BigDecimal.ROUND_UP 向上加1。
BigDecimal.ROUND_DOWN 直接舍去。
BigDecimal.ROUND_HALF_UP 四舍五入。
*/
3.2 BigDecimal 类的使用
java
package com.itheima.math01;
import java.math.BigDecimal;
public class BigDecimalDemo {
public static void main(String[] args) {
// BigDecimal(String value) 封装一个大小数对象
BigDecimal a = new BigDecimal("0.03");
BigDecimal b = new BigDecimal("0.02");
//加减乘除
System.out.println("a+b:"+a.add(b));
System.out.println("a-b:"+a.subtract(b));
System.out.println("a*b:"+a.multiply(b));
System.out.println("a/b:"+a.divide(b));
//除会除不尽 情况 出现了异常
BigDecimal d = new BigDecimal("1.0");
BigDecimal e = new BigDecimal("3.0");
/*
1.BigDecimal.ROUND_UP 向上加1。
2.BigDecimal.ROUND_DOWN 直接舍去。
3.BigDecimal.ROUND_HALF_UP 四舍五入
*/
System.out.println("d/e:"+d.divide(e,2,BigDecimal.ROUND_UP));//向上加一
System.out.println("d/e:"+d.divide(e,2,BigDecimal.ROUND_DOWN));//直接舍去
System.out.println("d/e:"+d.divide(e,2,BigDecimal.ROUND_HALF_UP));//四舍五入
}
}
第四章 基本类型包装类【重点】
4.1 包装类的概念
java
/*
包装类的概念
ArrayList集合存储基本类型数据时,要求<>中必须指定基本类型对应的引用类型(包装类)
基本类型 引用类型(包装类)
byte Byte
short Short
int Integer
long Long
float Float
double Double
char Character
boolean Boolean
集合中永远只能存储引用类型:
只需要在创建集合对象时,<>中指定对应的包装类,其它操作都可以按照基本类型完成
引用类型(包装类)并不是对基本类型的简单替换,而是包装类中提供了大量的方法完成相关功能
*/
java
package com.itheima.baozhuang;
import java.util.ArrayList;
public class BaoZhuangDemo {
public static void main(String[] args) {
// ArrayList<引用类型> 类 接口
// int 不是引用类型
// ArrayList<int> arrayList = new ArrayList<int>();泛型类型不能是基本类型
ArrayList<Integer> arrayList = new ArrayList<>();//采用包装类型去做
arrayList.add(11);//方法上要的参数 对象Integer类型 你写的是 数值
arrayList.add(12);//方法上要的参数 对象Integer类型 你写的是 数值
arrayList.add(13);//方法上要的参数 对象Integer类型 你写的是 数值
// 其实存的并不是int值 而是一个Integer对象
// 直不过 我们jvm编译期 帮你 完成了 int--Integer的转换
// int--Integer的转换 这种转换称为装箱
//基本类型 包装成了 对应的包装类对象 装箱
Integer num = arrayList.get(1);
int n = num;// 这里是 包装类型对象 转换成了 基本类型 这个操作称为拆箱
}
}
4.2 Integer 类对象的创建【重点】
java
/*
java.lang.Integer类对象的创建
Integer 类在对象中包装了一个基本类型 int 的值。
构造方法:
public Integer(int value):
把构造方法int参数value,转换成Integer对象
public Integer(String value):
把构造方法String参数value,转换成Integer对象
注意:
1.构造方法参数不可以超出int的范围
2.构造方法如果采用String的参数,参数中不可以包含非数字字符
*/
java
package com.itheima.baozhuang;
public class BaoZhuangDemo2 {
public static void main(String[] args) {
// int数据 123 转换成 Integer对象
// Integer i = 123;//自动的装箱
Integer i = new Integer(123);//把数值 123 包装成 包装类Integer类型
System.out.println(i.toString());
Integer ii = new Integer("123");//把字符串中的 数字字符串 包装成Integer类型
System.out.println(ii.toString());
//建议
Integer iii = 123;//体现了自动装箱
Double dou = 1.1;
Double d = new Double(1.1);
}
}
4.3 装箱 和 拆箱的概念
java
基本类型和对应包装类之间存在相互转换,装换的过程,称为"装箱"和"拆箱";
**装箱:**从基本类型转换为对应的包装类型。
**拆箱:**包装类型转换成基本类型。
装箱方法:
java
1:构造 new Integer(int i)
2:通过静态方法 static Integer valueOf(int i)
拆箱方法: (对象)参数引用类型,返回值是基本类型
java
int intValue()
将 Integer的值作为 int 。
这个方法是一个普通方法,需要Integer对象调用。
public static void main(String[] args) {
// 基本类型--引用类型
Integer integer = Integer.valueOf(10);
// 引用类型对象 转换成 基本类型
int i = integer.intValue();
System.out.println(i);
}
4.4 包装类的自动装箱拆箱
java
/*
包装类的自动装箱拆箱
自动装箱:
基本类型数据,可以自动转换为对应的引用类型(包装类),是自动完成滴,不需要代码特殊处理
自动拆箱:
引用类型数据(包装类),可以自动转换为对应的基本类型,是自动完成滴,不需要代码特殊处理
*/
java
// 自动拆装箱 也就是说 我们的写法变得简单了!!
// 写代码的方式可以变得简单 -- 这种简单的写法 JDK1.5之后进行优化的!
// 这是叫自动装箱和拆箱 你编译期代码可以简写 但是生成的.class文件底层 实际上还是上面的方式。
Integer integer1 = 10;//底层 Integer.valueOf(10);---明天老师讲一个面试题。
int i1 = integer1;//底层 integer.intValue();
java
ArrayList<Integer> list = new ArrayList<Integer>();
list.add(1);//有装箱 int类型 包装Integer类型
Integer i = 4;// 自动装箱 把4 包装成了一个 Integer对象
i = i+5;// 做加法的时候 先完成了拆箱 i 拆成了int 类型 4 + 5 = 9 9是int
//赋值的时候 完成了装箱
4.5 基本类型转换成对应的字符串 只掌握第一个
java
方式一 +空字符串
方式二 通过包装类 static String toString(int i)
方式三 通过String中的一个静态方法 static String valueOf(int i)
java
//int ---String
int a = 10;
//方式一
String s = a+"";
//方式二 通过包装类 int参数---String返回值
/*
static String toString(int i)返回一个 String指定整数的 String对象。
*/
String ss = Integer.toString(a);
//方式三 通过String中的一个静态方法 static String valueOf(int i)
String sss = String.valueOf(a);
4.6 String 解析成对应的基本类型 重要
java
/*
String解析成对应的基本类型(很常用的)
包装类中除了Character以外,每个包装类都会提供一个静态方法
public static xxx parseXxx(String str):
把方法参数String数据str转换成xxx类型的数据
Integer类:
public static int parseInt(String str):
把方法参数String数据str转换成int类型的数据
Double类:
public static double parseDouble(String str):
把方法参数String数据str转换成double类型的数据
Boolean类:
public static boolean parseBoolean(String str):
把方法参数String数据str转换成boolean类型的数据
*/
java
public class Demo07ParseString {
public static void main(String[] args) {
String str = "20";
//把String数据转换成int数据
int num = Integer.parseInt(str);
System.out.println(num);//20
System.out.println(num + 20);//40
System.out.println("---------------");
String str2 = "66.66";
//把String数据转换成double数据
double num2 = Double.parseDouble(str2);
System.out.println(num2);//66.66
System.out.println(num2 + 33.33);//99.99
System.out.println("---------------");
String str3 = "true";
boolean reslut = Boolean.parseBoolean(str3);
System.out.println(reslut);//true
System.out.println(!reslut);//false
}
}
第五章 异常【重点】
5.0 异常引入
异常:就是不正常,在程序执行过程中,出现了非正常的情况,最终导致了 JVM 非正常的结束。
NullPointException ClassNoCastException.
在 java 中,异常本身是一个类,在产生异常的位置,创建一个异常对象并抛出。默认的处理方式就是抛出给 JVM,JVM 中止程序。比如我们见到过索引越界异常。
java
public class ExceptionDemo01 {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
list.add("贾乃亮");
list.add("陈羽凡");
list.add("王宝强");
System.out.println(list.get(3));
System.out.println("这些人不容易~!");
}
}
5.1 异常的概念和体系
java
/*
异常:程序中的意外问题,处理异常,提供一种预防机制(预案),写字楼中的消防栓
异常的体系:
|--Object
|--Throwable 程序中可能会出现的所有的不正常的情况
|--Error 程序中的致命的问题,严重的错误
比如:绝症 一旦出现了Error,程序不能继续进行
|--Exception(编译时期的异常) 程序中的小的问题,小的错误,
比如:感冒,发烧,阑尾炎 只要将问题处理了,程序可以继续运行
异常和错误的区别
异常: 感冒 发烧 阑尾炎 可以处理 处理之后代码可以继续执行
错误: 癌症晚期 艾滋 非典 不能处理
名称:
错误: XxxError
异常: XxxException
*/
5.2 异常的分类【了解】
java
/*
异常的分类
|-- 编译时期异常:checked异常(受检测异常)。
在编译时期,就会检查,如果没有处理异常,则编译失败。(如日期格式化异常)
直接继承Exception
|-- 运行时期异常:runtime异常。
在运行时期,检查异常.
在编译时期,运行异常编译器不会检测(不报错)。(如数学异常)
不影响编译,可以正常生成.class文件,但是运行时期可能会出现问题
直接继承RuntimeException
*/
java
public class Demo01Exception {
public static void main(String[] args) throws ParseException {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
String strDate = "2020-09-24";
/*
parse方法内部声明抛出ParseException异常,
ParseException异常直接继承Exception,
说明是编译时期异常,在编译阶段必须处理(目前用throws处理),
不处理编译报错
*/
Date date = sdf.parse(strDate);
System.out.println(date);
System.out.println("-----------");
int[] array = {10, 20, 30};
/*
运行时期会报出索引越界异常:ArrayIndexOutOfBoundsException
ArrayIndexOutOfBoundsException继承RuntimeException,是
运行时期异常,不会影响编译,会产生.class文件,只不过在运行时期,
可能会产生这种问题
*/
int value = array[5];
System.out.println(value);
}
}
5.3 异常中常用的方法
Throwable--它里面的方法 所有的子类都有
java
printStackTrace(); 打印异常的详细信息
包含了异常的类型,异常的原因,异常出现的位置。----开发阶段如果我们想要异常信息就用这个方法。
java
String getMessage() 获取异常的描述信息(原因)
java
String toString() 把异常信息转换成字符串 出现了异常的类型和原因。
5.4 异常的产生和 JVM 处理异常的方式【重要】
java
/*
JVM默认的异常处理机制
1.打印异常信息
2.停止程序的执行(全都得死)
*/
public class Demo02Exception {
public static void main(String[] args) {
int[] array = {100, 200, 300};
int value = getValue(array, 5);
System.out.println("main方法中正确获取到数组元素值: " + value);
}
public static int getValue(int[] array, int index) {
int value = array[index];
System.out.println("getValue方法中正确获取到数组元素值: " + value);
return value;
}
}
第六章 异常处理
6.1 throw 的用法【重要】
java
/*
Demo02Exception中异常对象是由JVM创建并自动抛出的
如果我们想自己创建异常对象并手动抛出
需要使用throw关键字
throw关键字: 扔,抛的意思
throw关键字使用格式:
throw 异常对象;
throw new 异常类(...);
注意:
1.throw必须使用在方法内部
2.throw后面必须写异常对象,而且只能写一个
3.throw表示把一个具体的异常对象抛出给该方法的调用者
*/
java
public class Demo03ExceptionThrow {
public static void main(String[] args) {
int[] array = {100, 200, 300};
//array = null;
int value = getValue(array, 5);
System.out.println("main方法中正确获取到数组元素值: " + value);
}
public static int getValue(int[] array, int index) {
//如果数组是null,抛出空指针异常
if (array == null) {
throw new NullPointerException("数组array是null了,不能获取元素了?");
}
//如果索引越界,抛出索引越界异常
if (index < 0 || index >= array.length) {
throw new ArrayIndexOutOfBoundsException("数组索引越界了: "+index);
}
int value = array[index];
System.out.println("getValue方法中正确获取到数组元素值: " + value);
return value;
}
}
6.2 throws 声明抛出异常【重要】
java
/*
异常处理方式一:
使用throws关键字: 声明抛出异常
告诉方法的调用者,你调用我的方法时,我方法内部有可能会产生什么样子的异常,
方法内部没有处理,谁调用我谁来处理
使用格式:
修饰符 返回值类型 方法名称(形式参数列表....) throws 异常类 {
方法体;
}
场景:
项目经理: JVM
项目组长: main方法
程序猿: sports方法
注意:
1.throws关键字必须写在方法声明的后面
2.throws关键字后面跟的是异常类,而且可以写多个
3.throw必须使用在方法内部
4.throw后面必须写异常对象,而且只能写一个
5.throw表示把一个具体的异常对象抛出给该方法的调用者
*/
java
public class Demo04ExceptionThrows {
public static void main(String[] args) throws Exception {
System.out.println("组长安排程序员跑圈开始....");
sports(5);
System.out.println("组长安排程序员跑圈结束....");
}
//模拟程序猿锻炼身体: 跑圈
public static void sports(int num) throws Exception {
System.out.println("已经跑了3圈....");
if (num > 3) {
throw new Exception("心脏病发作....");
}
}
}
6.3 throws 声明抛出多个异常【了解】
java
/*
异常处理方式一:
使用throws关键字: 声明抛出多个异常
告诉方法的调用者,你调用我的方法时,我方法内部有可能会产生什么样子的异常,
方法内部没有处理,谁调用我谁来处理
使用格式:
修饰符 返回值类型 方法名称(形式参数列表....) throws 异常类1,异常类2 {
方法体;
}
场景:
项目经理: JVM
项目组长: main方法
程序猿: sports方法
*/
public class Demo05ExceptionThrows {
public static void main(String[] args) throws ParseException,FileNotFoundException {
System.out.println("开始读取文件内容...");
readFile(3);
System.out.println("结束读取文件内容...");
}
//模拟读取文件内容的方法
public static void readFile(int num) throws ParseException,FileNotFoundException {
if (num == 1) {
throw new ParseException("解析文件失败",num);
}
if (num == 2) {
throw new FileNotFoundException("文件不存在");
}
System.out.println("文件内容: 好好学习天天向上....");
}
}
6.4 try-catch 处理异常【重要】
try-catch 我们其实也可以对异常,尝试着进行抓取处理!
这种处理方式叫捕获异常。
捕获的格式:
java
try{
就是可能出现异常的代码;
}catch(异常类型 e){
你在这里可以对e进行判刑
}
它的出现 就替代了 throws 也就是我进行了捕获,说明我自己要试着处理了,就不麻烦别人了,就不用声明了。
java
package com.itheima.exceptionhandler;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.text.ParseException;
public class TryCatchDemo3 {
/**
try...catch 处理手法
尝试 抓取 异常
格式
try{
可能出现异常的代码;
}catch(异常类型 e){//这个异常类型用于接收抓取到异常对象
//你可以进行自己的任何处理 想怎么处理就怎么处理
}
替代了 throws
*/
public static void main(String[] args) {
System.out.println("开始解析文件");
try {
readFile(2);//试着 抓取 这里出现的异常
} catch (FileNotFoundException e) {//抓 FileNotFoundException这个异常
e.printStackTrace();//抓到异常之后的默认处理方式 打印异常详细信息
System.exit(0);//进行程序的停止
//给程序员发短信
}
System.out.println("解析文件完成");
}
//模拟读取文件内容的方法
public static void readFile(int num) throws FileNotFoundException {
if (num == 2) {
throw new FileNotFoundException("文件不存在");
}
System.out.println("文件内容: 好好学习天天向上....");
}
}
6.5 try-catch 处理异常流程【了解】
6.6 多 catch 处理异常【了解】
多个异常怎么处理 多个 catch , 需要如果有子父类关系,先处理子类再出父类。
建议我们直接写父类,就不用写子类了。你还可以直接写上级父类 Exception
java
package com.itheima.exceptionhandler;
import java.io.FileNotFoundException;
import java.io.IOException;
public class TryCatchDemo4 {
/**
try...catch 如何抓取多个异常
根据提示出来的处理方式 叫做 多catch处理方式
注意
最好 就使用父类异常 抓取
如果写了父类异常 还有子类异常 注意 子类异常要在上面
*/
public static void main(String[] args) {
System.out.println("开始解析文件");
try {
findFile("D:");
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
}catch (IOException e) {
e.printStackTrace();
}
System.out.println("解析文件完成");
}
public static void findFile(String path) throws ClassNotFoundException,FileNotFoundException, IOException {
if(path.contains("D:")){//如果盘符是D盘 就找不到文件
//怎么抛出异常
throw new FileNotFoundException("您访问的盘符都不存在,更别说文件了。");
}else if(path.contains(".txt")){//这种文件形式 在读取文件的时候会出现异常 IOException
//抛出一个IOException
throw new IOException("您的文件在读取的时候出现了异常");
}else{
System.out.println("可以找到文件");
throw new ClassNotFoundException("类找不到异常");
}
}
}
java
package com.itheima.exceptionhandler;
import java.io.FileNotFoundException;
import java.io.IOException;
public class TryCatchDemo5 {
/**
try...catch 如何抓取多个异常
根据提示出来的处理方式 叫做 多catch处理方式
注意
最好 就使用父类异常 抓取
如果写了父类异常 还有子类异常 注意 子类异常要在上面
最简单的方式 直接抓取最大的父类异常 Exception
*/
public static void main(String[] args) {
System.out.println("开始解析文件");
try {
findFile("D:");
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("解析文件完成");
}
public static void findFile(String path) throws ClassNotFoundException,FileNotFoundException, IOException {
if(path.contains("D:")){//如果盘符是D盘 就找不到文件
//怎么抛出异常
throw new FileNotFoundException("您访问的盘符都不存在,更别说文件了。");
}else if(path.contains(".txt")){//这种文件形式 在读取文件的时候会出现异常 IOException
//抛出一个IOException
throw new IOException("您的文件在读取的时候出现了异常");
}else{
System.out.println("可以找到文件");
throw new ClassNotFoundException("类找不到异常");
}
}
}
6.7 try-catch-finally 的使用【重要】
finally 代码块:
作用:在程序运行的时候,有些代码是不管程序是否有异常,一定要运行的。
对于这种代码,我只需要方法 finally 代码块中,就可以实现。
使用场景:用在 IO 流的释放中。
java
package com.itheima.exceptionhandler;
import java.io.IOException;
public class FinallyDemo {
public static void main(String[] args) {
try {
show();
System.out.println("没有问题 执行这句话");
} catch (IOException e) {
e.printStackTrace();
System.out.println("执行到这里 就出现了问题");
System.out.println("出现问题我让方法停止");
return;
}finally {
System.out.println("不管有没有异常 我都会执行");
}
System.out.println("我是over代码 结束代码");
}
public static void show () throws IOException{
throw new IOException("我是故意写出来的异常");
}
}
6.8 编译时期异常和运行时期异常的区别【重要】
java
异常:就是程序不正常了。可能就是我们代码或者代码相关的内容出现问题,我们应该发现问题,解决问题。
从而再减少问题。
在java中,把问题封装成了异常类。
Throwable
|---Error 错误,一般是非代码类问题,比如内存不够用了,内存溢出。
|---Exception 一般是代码类问题,平常说的异常。
|---编译期异常,可能出现问题的位置会在编译期提示。
特点: 一旦调用的功能中抛出过编译异常,就需要我们进行解决。
解决方案:
throws声明,一个是try-catch捕获。
一般来说 我们见到的编译期异常都是,我们操作跟外界因素有点关系,
出了问题两方面思考,代码问题,一个是外界问题。
io异常、文件找不到异常、类型解析异常、类文件找不到异常。
|---非编译期异常,编译阶段不会有异常的提示。
也可以使用 throws声明,一个是try-catch捕获。
因为解决操作有默认的机制,JVM进行的处理。
一般的问题就是代码不够严谨,有漏洞,俗称bug。你需要好好看发生的位置原因,进行解决。
throw关键字 抛出 在方法中使用。
throws 将异常声明出去,告知别人我这里有异常。
捕获 进行代码的监控,出现了异常就进行捕获抓取,进行对应的处理。
finally关键字 不是一定要用的,它有它的场景:有些代码,不管你程序如何,必须执行的就使用finally代码块。
6.10 异常后方法重写注意事项【了解】
java
运行期异常被抛出可以不处理(不声明,不捕获),因为JVM默认有解决方案。
1:如果父类方法抛出了异常,子类的方法如果重写可以不抛出异常,如果要抛那么就要和父类保持一致或者是父类异常子类。
2:父类如果没有异常,子类重写的方法就不能抛!
3:多异常catch处理的时候,子类要在父类前面。
4:throws可以直接声明大的异常,小的异常就不用声明。
父类中的方法抛了异常,那么子类重写之后要不要抛?
父类中的方法没有抛异常,那么子类重写之后要不要抛
java
//父类
public class Fu {
public void method() {
System.out.println("Fu...method....");
}
}
//子类
public class Zi extends Fu {
/*
父类method方法声明上,没有使用throws声明抛出异常
子类重写后的方法,内部有异常,不能使用throws
只能内部try-catch处理 ---使用场景: 在讲多线程(day09/day10)的时候会用到
*/
@Override
public void method()/* throws Exception*/ {
System.out.println("Zi...method...");
try {
throw new Exception("子类重写后出问题了!!!!");
} catch (Exception e) {
e.printStackTrace();
}
}
}
第七章 自定义异常【重要】
7.1 自定义异常简单演示
java
/*
自定义异常
虽然jdk中提供了大量的异常类,但是和我们实际的业务开发场景无关
所以我们需要根据需求自定义异常类
步骤:
1.自定义类继承Exception(编译时期异常)或者RuntimeException(运行时期异常)
继承谁都可以,没有统一规定
2.根据父类生成空参/满参构造
3.代码中就可以使用throw关键字抛出异常对象
*/
public class Demo12MyException {
public static void main(String[] args) {
try {
show();
} catch (UserNameRegisterException e) {
e.printStackTrace();
}
}
public static void show() throws UserNameRegisterException {
throw new UserNameRegisterException("用户名已经被注册了");
}
}
java
//自定义编译时期异常: 用户名已经被注册的异常类
public class UserNameRegisterException extends Exception {
//空参构造
public UserNameRegisterException() {
}
//满参构造
public UserNameRegisterException(String message) {
super(message);
}
}
7.2 自定义异常练习
java
/*
自定义异常练习
模拟注册操作,如果用户名已存在,则抛出异常并提示:亲,该用户名已经被注册。
实现步骤:
1.创建ArrayList集合list,存储数据类型String,模拟已经注册的用户
2.向ArrayList集合list添加多个字符串,代表已经注册的用户
3.定义方法判断新的用户名是否可以用
4.创建键盘录入对象
5.获取键盘录入的新的用户名,保存到String变量userName中
6.调用步骤3中定义的方法,判断新的用户名是否可用
*/
java
public class Demo13ExceptionTest {
public static void main(String[] args) {
//1.创建ArrayList集合list,存储数据类型String,模拟已经注册的用户
ArrayList<String> list = new ArrayList<>();
//2.向ArrayList集合list添加多个字符串,代表已经注册的用户
list.add("jack");
list.add("rose");
list.add("lucy");
list.add("lili");
list.add("hanmeimei");
list.add("lilei");
//4.创建键盘录入对象
Scanner sc = new Scanner(System.in);
//5.获取键盘录入的新的用户名,保存到String变量userName中
System.out.println("请输入您要注册的用户名: ");
String userName = sc.nextLine();
//6.调用步骤3中定义的方法,判断新的用户名是否可用
/*
checkUserName方法声明抛出了一个编译时期异常,必须处理
要么throws,要么try-catch
此处建议使用try-catch
原因: 这里可能是一个比较大的网站,不能因为注册用户失败,而影响用户使用其它功能
所以: 使用try-catch把这个问题处理掉,程序可以继续向下执行(用户可以继续完成除了注册以外的其它功能)
*/
try {
checkUserName(list,userName);
} catch (UserNameRegisterException e) {
e.printStackTrace();
}
System.out.println("看看其它图片....");
System.out.println("看看其它视频....");
}
//3.定义方法判断新的用户名是否可以用
public static void checkUserName(ArrayList<String> list, String userName) throws UserNameRegisterException {
//遍历集合
for (int i = 0; i < list.size(); i++) {
if (list.get(i).equals(userName)) {
/*
抛出编译时期异常,必须处理
要么throws,要么try-catch
此处建议使用throws,由调用者来处理此异常
因为: 一旦抛出此异常,说明用户名已经被注册,检测用户名是否被注册的这个方法的功能代码
没有必要继续执行了
*/
throw new UserNameRegisterException("非常抱歉用户名: "+userName+" 已经被注册...");
}
}
//执行到这里
System.out.println("恭喜您,用户名: "+userName+" 可以使用...");
}
}