一,异常机制
(一)基本概念
异常是程序中的一些错误,但并不是所有的错误都是异常,并且错误有时候是可以避免的。
比如说,你的代码少了一个分号,那么运行出来结果是提示是错误 java.lang.Error;如果你用System.out.println(11/0),那么你是因为你用0做了除数,会抛出 java.lang.ArithmeticException 的异常。
异常发生的原因有很多,通常包含以下几大类:
- 用户输入了非法数据。
- 要打开的文件不存在。
- 网络通信时连接中断,或者JVM内存溢出。
这些异常有的是因为用户错误引起,有的是程序错误引起的,还有其它一些是因为物理错误引起的。
(二)异常的分类
java.lang.Exception类是所有异常的超类,主要分为以下两种:
RuntimeException - 运行时异常,也叫作非检测性异常
IOException和其它异常 - 其它异常,也叫作检测性异常,所谓检测性异常就是指在编译阶段都能 被编译器检测出来的异常。其中RuntimeException类的主要子类:
ArithmeticException类 - 算术异常
ArrayIndexOutOfBoundsException类 - 数组下标越界异常
NullPointerException - 空指针异常
ClassCastException - 类型转换异常
NumberFormatException - 数字格式异常
注意: 当程序执行过程中发生异常但又没有手动处理时,则由Java虚拟机采用默认方式处理异常,而默认处理方式就是:打印异常的名称、异常发生的原因、异常发生的位置以及终止程序。
Exception 类是 Throwable 类的子类。除了Exception类外,Throwable还有一个子类Error 。
Java 程序通常不捕获错误。错误一般发生在严重故障时,它们在Java程序处理的范畴之外。
Error 用来指示运行时环境发生的错误。
例如,JVM 内存溢出。一般地,程序不会从错误中恢复。
异常类有两个主要的子类:IOException 类和 RuntimeException 类。
(常见异常背下来)(三)异常的避免
使用if判断避免异常
`package task12;
public class ExectionTest {
public static void main(String[] args) {
_//非检测性异常,运行时异常<br /> /* System.out.println(5/0);
检测性异常 不进行异常检测,则无法执行到运行阶段<br /> try {<br /> Thread.sleep(100);<br /> } catch (InterruptedException e) {<br /> e.printStackTrace();<br /> }*/<br /> _int ib=5;<br /> int ia=0;<br /> _//使用if语句判断避免异常<br /> _if (0!=ia) {<br /> System._out_.println(ib / ia);<br /> }<br /> else<br /> {<br /> System._out_.println("ia为0,不能进行运算");<br /> }
int [] arr1=new int [5];<br /> System._out_.println(arr1[5]);<br /> }<br />}
`
输出:
由上述程序可见,避免了算数异常,但是数组下标异常没有进行if判断则输出异常信息。
注意:
- 在以后的开发中尽量使用if条件判断来避免异常的发生。
- 但是过多的if条件判断会导致程序的代码加长、臃肿,可读性差。
(四)异常的捕获
语法格式
try {
编写可能发生异常的代码;
}
catch(异常类型 引用变量名) {
编写针对该类异常的处理代码;
} …
finally {
编写无论是否发生异常都要执行的代码;
}执行流程
try {
a;
b; - 可能发生异常的语句
c; }
catch(Exception ex) {
d;
}
finally {
e;
}
当没有发生异常时的执行流程:a b c e;
当发生异常时的执行流程:a b d e;
(上课案例)
代码段!
`package task12;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class ExectionTest {
public static void main(String[] args) {
_//非检测性异常,运行时异常<br /> /* System.out.println(5/0);
检测性异常 不进行异常检测,则无法执行到运行阶段<br /> try {<br /> Thread.sleep(100);<br /> } catch (InterruptedException e) {<br /> e.printStackTrace();<br /> }*/<br /> /* int ib=5;<br /> int ia=0;<br /> //使用if语句判断避免异常<br /> if (0!=ia) {<br /> System.out.println(ib / ia);<br /> }<br /> else<br /> {<br /> System.out.println("ia为0,不能进行运算");<br /> }
int [] arr1=new int [5];<br /> System.out.println(arr1[5]);*/<br /> _FileInputStream file=null;<br /> try {<br /> System._out_.println("1");<br /> file=new FileInputStream("d:/a.txt");<br /> System._out_.println("2");<br /> } catch (FileNotFoundException e) {<br /> System._out_.println("3");<br /> e.printStackTrace();<br /> System._out_.println("4");<br /> }<br /> try {<br /> System._out_.println("5");<br /> file.close();<br /> System._out_.println("6");<br /> } catch (IOException e) { _//由于是系统自动处理得,所以输出异常的message后,后面的代码不会执行<br /> _System._out_.println("7");<br /> e.printStackTrace();<br /> System._out_.println("8");<br /> }<br /> catch (NullPointerException e) {<br /> System._out_.println("9");<br /> e.printStackTrace();<br /> System._out_.println("10");<br /> } _//手动处理异常,后面的代码和catch捕获的异常信息都会输出<br /> _System._out_.println("世界上最真情的相依是你在try我在catch,无论你发神马脾气我都默默承受静静处理,直到fially的来临");<br /> }<br />}`
手动处理异常和不手动处理的区别:
代码是否能继续往下执行!
注意事项
a.当需要编写多个catch分支时,切记小类型应该放在大类型的前面;
b.懒人的写法: catch(Exception e) {}
c.finally通常用于进行善后处理,如:关闭已经打开的文件等。
cath(Exception e){
e.printStachTrace();
}
要放在后头,不能放在前头,因为Exception的类型比较大。
(5)finally的应用
不处理时,发生空指针异常,finally依旧执行,而底下的输出语句则不会再输出!
笔试考点*:
定义一个方法,并在main方法调用该方法,输出的结果是?
解:
输出的是2,因为finally最后执行
(五)异常的抛出
(1) 基本概念 :
在某些特殊情况下有些异常不能处理或者不便于处理时,就可以将该异常转移给该方法的调用者, 这种方法就叫异常的抛出。当方法执行时出现异常,则底层生成一个异常类对象抛出,此时异常代 码后续的代码就不再执行。
- 语法格式
访问权限 返回值类型 方法名称(形参列表) throws 异常类型1,异常类型2,…{ 方法体; }
如: public void show() throws IOException{}
- 方法重写的原则
a.要求方法名相同、参数列表相同以及返回值类型相同,从jdk1.5开始支持返回子类类型;
b.要求方法的访问权限不能变小,可以相同或者变大;
c.要求方法不能抛出更大的异常;
- 注意:
子类重写的方法不能抛出更大的异常、不能抛出平级不一样的异常,但可以抛出一样的异常、更小 的异常以及不抛出异常。
- 经验分享
若父类中被重写的方法没有抛出异常时,则子类中重写的方法只能进行异常的捕获处理。<br /> 若一个方法内部又以递进方式分别调用了好几个其它方法,则建议这些方法内可以使用抛出的方法处理到最后一层进行捕获方式处理。
(六)自定义异常
(1)基本概念
当需要在程序中表达年龄不合理的情况时,而Java官方又没有提供这种针对性的异常,此时就需要
程序员自定义异常加以描述。
(2)实现流程
a.自定义xxxException异常类继承Exception类或者其子类。
b.提供两个版本的构造方法,一个是无参构造方法,另外一个是字符串作为参数的构造方法。
异常的产生
throw new 异常类型(实参);
如:
throw new AgeException(“年龄不合理!!!”);
Java采用的异常处理机制是将异常处理的程序代码集中在一起,与正常的程序代码分开,使得程序
简洁、优雅,并易于维护。
参考传送门:https://zhuanlan.zhihu.com/p/66228306
(七)总结
二、File类
(1)基本概念
java.io.File类主要用于描述文件或目录路径的抽象表示信息,可以获取文件或目录的特征信息,
如:大小等。
(2)常见方法
(2.1)文件和目录的创建
package Task_neuedu;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class FileTest {
public static void main(String[] args) throws IOException {
File f1=new File("E:/a.txt");
if (f1.exists()){
System.out.println(f1.getAbsoluteFile()); //获取绝对路径
System.out.println(f1.getName()); //获取文件名
System.out.println(f1.length()); //获取文件长度
//System.out.println(f1.lastModified()); //获取文件最近修改的时间
Date date=new Date(f1.lastModified());
SimpleDateFormat sdf=new SimpleDateFormat("YYYY-MM-dd hh:mm:ss"); //格式化
System.out.println(sdf.format(date));
}
else {
System.out.println(f1.createNewFile()?"创建成功":"创建失败"); //如果没有存在该文件就创建一个
}
System.out.println("------------------------------");
//目录的创建和删除
File f2=new File("d:/二级目录/三级目录");
boolean b=f2.exists();
if (b){
System.out.println("目录名称是:"+f2.getName());
System.out.println(f2.delete()?"目录删除成功":"目录删除失败");
}
else {
System.out.println(f2.mkdirs()?"创建成功":"创建失败");
}
}
}
(2.2)目录的遍历
package Task_neuedu;
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class FileTest {
public static void main(String[] args) throws IOException {
File f1=new File("E:/a.txt");
if (f1.exists()){
System.out.println(f1.getAbsoluteFile()); //获取绝对路径
System.out.println(f1.getName()); //获取文件名
System.out.println(f1.length()); //获取文件长度
//System.out.println(f1.lastModified()); //获取文件最近修改的时间
Date date=new Date(f1.lastModified());
SimpleDateFormat sdf=new SimpleDateFormat("YYYY-MM-dd hh:mm:ss"); //格式化
System.out.println(sdf.format(date));
}
else {
System.out.println(f1.createNewFile()?"创建成功":"创建失败"); //如果没有存在该文件就创建一个
}
System.out.println("------------------------------");
File f2=new File("d:/二级目录/三级目录");
boolean b=f2.exists();
if (b){
System.out.println("目录名称是:"+f2.getName());
System.out.println(f2.delete()?"目录删除成功":"目录删除失败");
}
else {
System.out.println(f2.mkdirs()?"创建成功":"创建失败");
}
//实现将指定的目录内容打印出来
File f3=new File("d:/二级目录/三级目录");
File[] files = f3.listFiles();
for (File file2:files) {
if (file2.isFile()){ //如果是文件,用中括号
System.out.println("["+file2.getName()+"]");
}
if (file2.isDirectory()){ //如果是目录,用大括号
System.out.println("{"+file2.getName()+"}");
}
}
System.out.println("------------------------------");
//匿名内部类 接口/父类型 变量名=new 接口/父类型(){重写的方法}
FileFilter fileFilter=new FileFilter() {
@Override
public boolean accept(File pathname) {
//若文件以.txt结尾的则返回true,表示保留,返回false,则表示过滤
return pathname.getName().endsWith(".txt");
}
};
//使用lambda表达式:(参数列表)->{方法体}
FileFilter fileFilter1=(File pathname)->{return pathname.getName().endsWith(".txt");};
File [] files1=f3.listFiles(fileFilter);
for (File f:files1
) {
System.out.println(f.getName());
}
}
}
https://blog.csdn.net/u014453898/article/details/79655338(参考)