目录
异常[Exception]
java异常结构
java异常结构定义有,Throwable、Exception、Error
Exception与Error 是其派生的两个子类
Exception:网络故障、文件损坏、设备错误、用户输入非法等情况导致的异常
例如:int k=10/0; //java.lang.ArithmetticException
Error:java运行时环境出现错误
例如:jvm资源耗尽
异常捕获,就是当异常发生时妥善地终止程序,避免灾害性后果的发生
具体操作包括:
通知,向用户通知异常的发生;
恢复,保存重要的数据,恢复文件,回滚事务等;
退出,以更好的方式结束程序的运行
try…catch
try{…}语句中的代码,就是捕获异常的范围,
try {…}语句里面的代码,执行后有可能会抛出异常;
若抛出异常,则进入catch语句块;
若异常未发生,则跳过catch语句块
Exception 所有异常类的父类 向上造型 捕获所有异常
//两数相除
Scanner scanner=new Scanner(System.in);
System.out.println("输入两个整数,除法运算");
int divi=0;
try {
int n1= scanner.nextInt();
int n2= scanner.nextInt();
divi=n1/n2;
}catch (Exception e){
e.printStackTrace();
//提示程序员,是什么异常,参考异常修改 //直接输出
System.out.println(e.getMessage());
//返回字符串
System.out.println("输入数据有误");
System.out.println("结果为"+divi);
}
System.out.println("运算结果为"+divi);
//try...case执行完后,到后续代码
若未捕获异常[即不使用try…catch]
程序员未自己处理,则出现异常就会抛出去
由于在main方法中,则该异常就会抛给jvm,jvm会把异常的堆栈信息打印到控制台
多个catch
在执行try语句块的过程中,该段代码可能会抛出一种或多种异常
catch语句块可以分别对不同的异常做处理[只会执行到一个catch中]
Exception 所有异常类的父类 向上造型 捕获所有异常
捕获所有异常
try …catch(Exception e) …
//捕获所有异常
try {
String s=null;
System.out.println(s.length());
int[] k={1,3,4};
System.out.println(k[k.length]);
String s1="100a";
int b=Integer.parseInt(s1);
}catch (Exception e){
//Exception 所有异常类的父类 向上造型
e.printStackTrace();
}
System.out.println("欢迎使用!");
}
每种异常,单独捕获,单独处理
try…catch(类型 e)…catch(类型 e1)…多个catch,只会执行其中一个catch语句块
//多个catch ,只会执行其中的一个catch语句块。
try {
String s = null;
System.out.println(s.length()); // 空指针
int[] k = {1,3,4};
System.out.println(k[k.length]); // 数组越界
String s1 = "100a";
int b = Integer.parseInt(s1); // 格式化
int k1 = 10/0; // 运算异常。
}catch (NullPointerException e){
// Exception是所有异常类的父类。 向上造型。
System.out.println("空指针:" + e.getMessage());
}catch (ArrayIndexOutOfBoundsException e){
System.out.println("数组越界:" + e.getMessage());
}catch (NumberFormatException e){
System.out.println("数据格式化异常:" + e.getMessage());
}catch (RuntimeException e){
// 先捕获子的异常类型, 再捕获父的异常类型。
System.out.println("运行时异常。");
}
System.out.println("欢迎使用!"); // 必须要执行到这里
//多个catch ,只会执行其中的一个catch语句块
// 这里发生的异常,没有被catch到 ,所有程序就抛出异常,后续代码无法执
多个catch 先捕获小[子]的异常,后捕获大[父]的异常;
当发生的异常没有被捕获到,则所有程序抛出异常且后续代码无法执行
throw 与 throws
throw
throw,通过throw语句将异常抛出,被抛出的异常可以让其他代码来捕获这个异常;
若需自行抛出异常,则需要使用throw关键字并创建出抛出的异常类的对象
throw new XXXException();
throw一次只能抛出一个异常,且抛出异常后将不再执行后续代码
使用throw抛出异常,就不需要return
可使用throw语句抛出异常
在调用该方法时,可选择捕获异常[try…case]
或者在调用该方法时,直接抛出异常
即直接抛出异常给jvm,jvm会把异常的堆栈信息打印到控制台
调用该方法时,可选择捕获异常[try…case]
直接抛出,jvm打印
若执行了 throw 语句,一定会抛出一个异常
使用throws抛出异常
在方法声明的时候,使用throws抛出异常;
那么就由该方法的调用者,来处理这个异常捕获异常,或者继续抛出异常
Exception 包含了运行时异常和非运行时异常
因此需要在编译期间对其异常进行捕获或抛出
throws,方法签名的时候使用, 可以抛出多个异常
可能存在编译异常时,需要在编译期间对其进行捕获或抛出
throws声明的方法,可能会抛出的异常,需进行捕获
throws ,是用来声明当前方法有可能会出现某种异常的;
如果出现了相应的异常,则抛出异常让调用者来处理
声明了的异常,不一定会出现异常,但调用者必须对其进行捕获或抛出处理
throws 方法签名的时候使用, 可以抛出多个异常
public static int age(int data , String birth) throws
ParseException,AgeException {
// throws-- 方法签名的时候使用, 可以抛出多个异常。
if(data > 120 || data < 0 ){
// 使用了throw 抛出异常,就不需要return。
throw new AgeException("年龄需要在0~120");
}
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
try {
sdf.parse(birth);
}catch (ParseException e){
throw new ParseException("这个生日格式错误,转换不了日期。" ,100);
}
return data;// 正常的年龄。
}
}
class AgeException extends Exception{
// Exception 包含了运行时异常和非运行时异常
public AgeException(String s){
super(s);
}
}
throw 与 throws的区别
throw作用在方法体内,用来抛出一个具体的异常类型对象,一次只能抛出一种异常;
throws 作用在方法签名中,用来声明一个方法可能产生的所有异常,可以有多个异常类名,用逗号隔开,表示抛出异常,且由该方法的调用者来处理这个异常;
throw 在方法体内使用,throws在方法声明上使用
throw 后面接的是异常对象,只能接一个;throws后面接的是异常类型,可以节多个,且多个异常类型用逗号分开;
throw ,是在方法中出现不正确情况时,手动来抛出异常,结束方法的;执行了 throw 语句一定会抛出一个异常;
throws ,是用来声明当前方法有可能会出现某种异常的;如果出现了相应的异常,则抛出异常让调用者来处理,声明了的异常不一定会出现异常
RuntimeException运行时异常
RuntimeException,运行时异常
程序运行过程中,由某些特定操作引发的异常,被称为运行时异常
IllegalArgumentException
NullPointerException
ArrayIndexOutOfBoundsException
CalssCastException
NumberFormatException
RuntimeException
finally
无论try语句块中是否有异常,finally语句块的内容都会被执行
finally语句,为异常处理提供一个统一的出口,使得在控制流程转到其他程序其他部分之前,能够对程序的状态做统一管理
通常在finally语句块中完成一些必须要执行的代码。比如: 文件的关闭,数据库的关闭等
try…catch…finally…
Scanner s=new Scanner(System.in);
try {
System.out.println("输入一个字符串:");
String s1=s.next();
System.out.println("输入一个整数:");
int data=s.nextInt();
}catch (Exception e){
e.printStackTrace();
throw new RuntimeException();//抛出异常,不会再向运行,运行结束
}finally {
s.close();//保证正常与异常结束,都能执行到这个代码块
System.out.println("流关闭....");
//正常结束,执行完finally,还会向下执行;
//异常结束,执行完finally,会再向下执行即运行结束
}
System.out.println("程序结束");
finally相关笔试题
try…catch …finally : finally语句块的内容始终要执行;
即使,try…catch中的return语句,也不能阻止finally代码块的运行
但System.exit(0); 会终止整个程序
推算以下k的值是多少
主函数
public static void main(String[] args) {
int k=test2();//12
}
代码一
public static int test2(){
//finally 必须执行即使存在return,也需要先执行完finally,再返回
int a=10;
try {
int k=1;
int m=10/k;
a++;
return a;
}
catch (Exception e){
a++;
return a;
}
finally {
a++;
return a;
}
}
代码二
public static int test2(){
//finally 必须执行即使存在return,也需要先执行完finally,再返回
int a=10;
try {
int k=0;
int m=10/k;
a++;
return a;
}
catch (Exception e){
a++;
return a;
}
finally {
a++;
return a;
}
}
代码三
public static int test2(){
//finally 必须执行即使存在return,也需要先执行完finally,再返回
int a=10;
try {
a++;
int k=0;
int m=10/k;
return a;
}
catch (Exception e){
a++;
return a;
}
finally {
a++;
return a;
}
}
final, finally, finalize的区别
final,是关键字,“最后的、不可修改的”;
一般修饰类,表示此类不可被继承;
修饰方法,表示此方法不可被重写[可被自身重载];
修饰成员变量,表示此成员变量为常量且必须给予初始值,不可再被修改
finally,关键字,用于异常处理;
在try…catch…finally中,无论程序是正常运行还是异常运行,最后都要运行到finally中;
即使存在return,返回值,也不能阻止;
finalize,属于Object类的一个方法();
高版本中不建议再使用,由垃圾回收器调用;
当程序员调用System.gc(),垃圾回收器调用finalize()该方法,判断这个对象是否可回收
自定义异常类
程序员可以自定义异常,解决自己程序中的一些特定内容
//自定义异常使用
//定义的异常类,主要使用super()去调父类的构造器,使用super.方法去调父类的方法
public class Demo5Exception {
public static void main(String[] args) {
try {
throw new GenderException("hello");
}catch (GenderException e){
System.out.println(e.getMessage());//输出创建对象时,传入的字符串
e.printStackTrace();//打印堆栈信息
}
}
}
//编译时异常,编译时需要处理这个异常
class GenderException extends Exception{
//定义构造函数
public GenderException() {
}
public GenderException(String message) {
super(message);
}
//重写普通方法
@Override
public String getMessage() {
return super.getMessage();//调用父类
}
@Override
public void printStackTrace() {
super.printStackTrace();//调用父类
}
}
//运行时异常,运行时才会抛出异常
class GenderException1 extends RuntimeException{
}
重写的异常处理
如果父类的方法抛出了异常,那么子类重写父类的时候,
异常可以如下处理:
不处理异常(重写的时候,不抛出异常)
可以只抛出部分异常
可以抛出异常的子异常
抛出其他运行时异常
但是不可以如下操作:
重写的时,抛出父类方法没有抛出的非运行时异常
重写的时,抛出父类没有抛的Exception
父类
class A{
public void print() throws NumberFormatException,ArithmeticException{}
public void print1(){}
}
异常类[自定义]
class E extends NumberFormatException{}
子类
class B extends A{
可以自己抛出,运行时异常
public void print1(){}
子类和父类抛出一样异常
public void print1() throws NullPointerException{}
public void print() throws NumberFormatException,ArithmeticException {super.print();
父类的方法抛出异常,子类选择不抛异常
public void print(){}
抛出了其他运行时异常
public void print() throws NullPointerException{}
抛出子异常
public void print() throws E{
抛出子父类方法的部分异常
public void print() throws NumberFormatException{
}
编译错误:不可以自己抛出非运行时异常
public void print1() throws ParseException{ }*
编译错误:重写的时候抛出父类没有抛的Exception
public void print() throws Exception{ }
重写的时候抛出父类方法没有抛出的非运行时异常
public void print() throws ParseException{ }
}
File(文件或目录)
java.io.File用于表示文件(目录)
程序员可以通过File类在程序中操作硬盘上的文件或目录
File类只用于表示文件(目录)的信息(大小,名称等),不能对文件内容进行访问
构造器函数:File(String path)
常用方法
构造器函数 File(String path)
length() 文件长度long;
lastModified() 最后一次修改时间long;
getName() 文件或目录名称String;
getAbsolutePath() 文件绝对路径
getPath() 路径转换为一个路径名字符串String
exists() 表示文件/目录是否存在 boolean;
isFile()文件、isDirectory()目录 是否为标准文件或目录 boolean;
canRead()\canWrite() 是否可读取、修改 boolean;
对象.delect()删除
对象.mkdir(); 创建文件夹
对象.createNewFile();创建文件
public static void main(String[] args) throws IOException {
//创建对象
File file=new File("C:\\Users\\LY\\Desktop"); //目录
File file1=new File("C:\\Users\\LY\\Desktop\\2023.7.31作业.docx");//文件
System.out.println(file.isDirectory());
System.out.println(file.isFile());
//找file名字 file1.getName()、file1.getAbsolutePath() String
System.out.println(file1.getName());//2023.7.31作业.docx
System.out.println(file1.getAbsolutePath()); //Absolute 绝对路径包含(盘符)
//C:\Users\LY\Desktop\2023.7.31作业.docx
//找file1的后缀名 子字符串
String str=file1.getName();
System.out.println(str.substring(str.lastIndexOf(".")+1));
//文件大小
System.out.println(file1.length());//13798 字节
//看是否能可读可修改
System.out.println(file1.canRead());//true
System.out.println(file1.canWrite());//true
//文件存在
System.out.println(file1.exists());//true
//file1.createNewFile();//创建新文件
//在桌面创建叫a的文件夹,在a文件夹中,创建一个叫b.txt
//创建两个对象的路径
if(file.isDirectory()){
File f2=new File(file.getAbsolutePath()+"\\a");
f2.mkdir();
File f3=new File(f2.getAbsolutePath()+"\\b.txt");
f3.createNewFile();
}
long l=file1.lastModified();//最后修改时间 并转化为Date类型
Date d=new Date(l);
SimpleDateFormat s=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println(s.format(d));
}
递归查看文件和删除文件
public static void main(String[] args) {
File file=new File("C:\\Users\\LY\\Desktop\\llll");
//seeFile(file);
delectFile(file);
}
public static void seeFile(File file){
if(file.isDirectory()){
File[] files=file.listFiles();
for (File f:files)
seeFile(f);
}else {
System.out.println(file.getAbsolutePath());
}
}
public static void delectFile(File file){
if(file.isDirectory()){
File[] files=file.listFiles();
for (File f:files)
delectFile(f);
file.delete();
}
else {
file.delete();
}
}
面试题:常见的异常类型
NullPointerException 空指针异常,
ClassCastException 强制类型转换异常
NumberFormatException 数字格式异常
NoSuchMethodException 方法不存在异常
FileNotFoundException 找不到文件异常
ClassNotFoundException找不到类异常
IndexOutOfBoundsException 索引异常
ArrayIndexOutOfBoundException 数组下标越界异常
StringIndexOutOfBoundException 字符串越界异常
IOExcption 读写数据的输入输出异常
EOFException 流异常到底文件末尾
SQLException 数据库异常
OptionalDataExceprion 反序列化顺序错误异常
InputMismatchException 输入不匹配异常
ArithmeticException 算数异常