异常
程序中的异常:在运行代码的时候,发生错误
异常就是一个对象所有的异常提示信息与报错的位置都是封装在这个类里
异常的体系结构
- Throwable,在java中,这就类是所有异常的父类
- Error,错误,这种错误是比较严重的错误,一般jvm产生,这种一般解决不了,解决需要改jvm的原代码;
- Exception,不是特别严重的错误的异常,这种异常必须解决
- RuntimeException,这种异常可以不捕获,也就是不用去解决
解决异常的方式:
- 抛出异常,给调用者解决
- 自己解决,也就是主动捕获异常
jvm 默认解决异常
- 打印异常的错误信息(异常类型 异常出现的位置)
- 终止程序
注意点:如果方法的调用用产生了异常,但是调用者都没有处理这个异常,最后这个异常就由jvm来处理(踢皮球)
常规的异常 : .
- ArithmeticException 算数异常
- NullPointerException 空指针异常
- IndexOutOfBoundsException下标越界异常
- ClassCastException 强制类型转换异常
- ParseException 格式化异常
自身处理异常:
异常的关键字有5个,try,catch,finally,throw,throws
第一种处理异常的方式: try-catch
//异常的语法格式是:
try{
//包含的是可能发生异常的代码
}catch(ArithmeticException e){ //声明异常
//发生异常之后所执行的代码
}
执行的流程:
- 当不发生异常时候:正常执行 try{} 代码
- 当执行 try{} 里的代码发生了异常,就会执行 cacth 里的代码
注意点:出现的异常必须与catch中申明的异常匹配,才能执行catch里的代码
多种异常出现的情况 :
//异常的语法格式:
try{
//包含的是发生异常的代码
}catch(ArithmeticException e){ //异常的声明1
//执行异常1代码
}catch(Exception e){ //异常的声明2
//执行异常2代码
}
注意点:
- 如果存在多个 cacth, 一般发生异常,匹配的规则是从上到下进行匹配,如果发生的异常与cacth 里声明的异常匹配, 就执行当前catch里的代码,不会执行后面的cacth 代码
- 多个catch中,异常是由小到大进行排列,一般是最大的异常最后面
- 多个异常可以使用 | 来连接多个异常
public class Test {
public static void main(String[] args) {
try{
System.out.println(1/0);
}catch (Exception e){
//e.printStackTrace(); //输出异常信息
System.out.println("error");
System.out.println(1/0);
//try{}中发生异常则进入catch{}
//catch执行完成,继续执行接下来的代码
}finally {
System.out.println("我一定会回来的");
//一定会执行
//即使try{}和catch{}都发生了异常,或者没有发生异常,或者有return语句
//一般用于关闭资源
}
System.out.println("continue");
}
}
第二种处理异常的方式 try-catch-finally
//异常的语法格式:
try{
//可能发生异常的代码
}catch(Exception e){ //异常的声明
//执行异常代码
}finally{
//不管发生不发生或者不发生异常,都会执行的代码
}
- finally 的代码不管发生不发生异常都会执行,除非虚拟机关机
- 遇到return关键字之后,先执行值finally的代码,然后再执行return
- finally的作用:一般用于关闭资源,比如io资源
- 不建议在最前面给大异常Exception,这样不能提高找bug的效率,一般是最后给大异常
- 不是把所有的代码都放在try里,因为try代码会检查,所有运行效率肯定是慢的
- 所有申明的异常必须是Exception或者是它的子类
public class Test {
public static void main(String[] args) {
System.out.println(new Test01().t());
}
public int t(){
int i=0;
try{
return i; //执行返回,继续执行finally
}finally {
i=1; //无法修改return的值
System.out.println("hello"); //先于main方法输出
return i; //可以修改return的值
}
}
}
第三种处理异的方式 try-finally
//异常的语法处理格式:
try{
//可能发生异常的代码
}finally{
//不管发生不发生或者不发生异常,都会执行的代码
}
作用:
- 使得两段代码进行分离,代码的结构更加清晰
- 不管是否发生异常,都会执行finally的代码
异常的分类:
- 编译时异常:也就在没有遍历时候代码出现的错误
- 运行时异常: 一般的异常都是 Exception 的子类,这种异常是必须要处理,RuntimeException可以不处理
Throwable是所有异常类的直接父类或者是间接父类
构造方法:
- public Throwable() 无参构造
- public Throwable(String message) 把产生的消息封装到Throwable
- public Throwable(String message,Throwable cause) 把产生的消息与 Throwable 重新构建一个新的Throwable 对象
- Throwable(Throwable cause) 重新构建一个新的Throwable 对象
常规的方法:
- public String getMessage():返回此throwable的详细消息字符串。
- public void printStackTrace():打印的是堆栈的错误信息
- public String toString() 打印简短的错误
抛出异常:throw
public void show() throws Exception {
throw new Exception("hello"); //抛出异常
}
- hrow一般是写在方法里
- 方法里throw之后的语句不会执行
- 声明时异常必须使用Exception或者是其子类
- 声明的异常如果是RuntimeException,表示没有意思,不需要去处理
好处: throw,自行抛出异常,可以按照自己习惯来进行异常的抛出
声明异常:throws
public void show() throws Exception { //声明该方法可能抛出此异常
...
}
注意点:
- 写在方法的括号后面
- throws 跟的异常必须比方法内部声明的异常范围,要大,或者是其本身
- throws 可以跟多个异常
- throws RuntimeException 抛出这种异常,使用此方法时可以不处理
- throws 抛出的异常,如果调用者不处理,最后就给jvm进行处理
throw 与 throws 的区别 :
- 写的位置不一样 throw 是在方法的内部,throws 是在方法的小括号后面
- throw 表示抛出异常对象,throws 声明异常
- throw 说明肯定会发异常,throws 不一定发生异常
- throw 后面只能跟一个异常,throws 可以跟多个异常
- 一般在开发中throw 与 throws搭配的使用
自定义异常使用的场景:
- 系统提供的异常都不能满足我们的要求
- 在开发写sdk 或者是jar包
自定义异常:
- 命名规范: xxxException,例如:MyRunException
自定义异常的步骤
- 一般是继承Exception或RuntimeException
- 调用的父类的构造
//自定义异常
public class MyRunExecption extends Exception{
public MyRunExecption(String message) {
super(message);
}
}
注意: 在继承中父类用什么用异常,子类就使用什么异常(避免一些不必要的错误)
File
导包是:java.io.File
构造方法:
- public File(String pathname):pathname 表示是文件的路径
- public File(String parent, String child):parent - 父路径名字符串,子路径名字符串
- public File(File parent,String child):parent 父路径的文件对象 子路径名字符串
- public File(URI uri):uri 网址(服务器路径)
常规的一些方法:
创建:
- public boolean createNewFile()throws IOException:创建文件,创建成功 返回true,失败返回false
注意点:如果是在文件夹下创建文件,文件夹先必须存在 - public boolean mkdir():创建文件夹
- public boolean mkdirs() 如果父目录不存在,也会把父目录一起创建
删除:
- public boolean delete():删除文件
删除的文件在电脑的回收站是找不到
这个方法只能删除空的文件夹
剪切/重命名:
- public boolean renameTo(File dest)
剪切:不在同一个文件夹下的时候,执行的是剪切
重命名 :在同一个问价夹下的时候,执行是重命名
判断性:
- public boolean exists() 判断这个文件是否存在
- public boolean isDirectory() 判断是否是目录
- public boolean isFile() 判断是否是文件
- public boolean isHidden() 判断是否是隐藏文件
获取性:
- public String getAbsolutePath() 获取的是文件的绝对路径
- public String getName() 返回的是文件的名称
- public String getParent() 获取其父目录
- public String getPath() 返回的是构造方法传递的路径
- public long length() 获取文件的大小
- public File[] listFiles() 获取当前文件夹所有的文件包含.txt等文件
- public File[] listFiles(FileFilter filter) 传递的是过滤器,对某些文件进行过滤
public class Test {
public static void main(String[] args) throws IOException {
File file = new File("E:/test.txt");
System.out.println(file.length());
System.out.println(file.delete()); //删除文件
System.out.println(file.createNewFile()); //创建文件
System.out.println(file.exists()); //是否存在
System.out.println(file.getPath()); //获取文件路径
System.out.println(file.isFile()); //是否是文件
System.out.println(file.isDirectory()); //是否是文件夹
File temp = new File("E:/t.txt");
System.out.println(file.renameTo(temp)); //重命名
}
}
递归
在开发中的递归,就是方法自己反复调用自己
- 递归效率比较低,容易出现栈内存溢出异常
java.lang.StackOverflowError - 递归的时候要有一个限制范围
//斐波那契数
public class Test {
public static void main(String[] args) {
for(int i=0;i<=30;i++){
System.out.println(helper(i));
}
}
public static int helper(int num){
if(num==0||num==1){
return 1; //基本条件
}
return helper(num-1)+helper(num-2); //调用自身
}
}