2020.05.23课堂笔记
异常机制
-
什么是IO流(InputStream ,OutputStream,输入输出流 )
- 在Java中IO流用于设备之间的数据传输。
-
我们在下载或者上传途中出现问题,那就需要我们解决。
-
Java中遇到问题有一个类来描述,Throwable类
- Throwable:问题或者错误的父类
- Exception:描述一般性问题异常
- 编译期异常:发生在编译期间(非RuntimeException及其子类)
- 处理方式一:使用关键字throws,向上抛出,抛给调用者处理,谁调用谁处理。最终还是虚拟机来处理。
- 方式二:自己捕获处理try…catch。
- 运行期异常:可以解决,也可以不解决。
- 不解决时,Java就使用默认处理方式–Java就会打印异常的堆栈信息,并退出虚拟机。
- 不满意自动处理结果,需要自己处理运行期异常:自己提示异常信息,但不退出虚拟机。需要使用使用关键字try … catch.
- 编译期异常:发生在编译期间(非RuntimeException及其子类)
注意:异常的处理不要做空处理,给出一句话也行。
运行期异常
package org.westos.demo0523;
/*Author:LH
CreatTime:2020.05.23.20:41*/
public class MyTest {
public static void main(String[] args) {
int a=10;
int b=0;
// 因为在运行期出现了异常,虚拟机会把异常的信息打印出来,并且退出虚拟机。
// 下面的程序不会执行
// double c=a/b;
// System.out.println(c);
// ArithmeticException: / by zero 会报错因为除数为0。
double c=0;
// 因此我们使用try...catch关键字,捕获处理异常。
try {
c=a/b;
}catch (ArithmeticException e) {
System.out.println("除数为0了");
}
System.out.println(c);
}
}
2. package org.westos.demo0523;
/*Author:LH
CreatTime:2020.05.23.15:41*/
//新方法判断 输入的是否是需要的类型
import java.util.InputMismatchException;
import java.util.Scanner;
public class MyException {
public static void main(String[] args) {
System.out.println("请输入成绩");
while (true) {
try {
Scanner sc = new Scanner(System.in);
int i = sc.nextInt();
System.out.println(i);
break;
} catch (InputMismatchException mis) {
System.out.println("输入不合法,请重新输入");
}
}
}
}
编译期异常
package org.westos.demo0523;
/*Author:LH
CreatTime:2020.05.23.21:49*/
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class MyTest4 {
public static void main(String[] args){
String date="2020-11=14";
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
Date parse = null;
try {
parse = dateFormat.parse(date);
} catch (ParseException e) {
System.out.println("解析格式错误");
}
System.out.println(parse);
}
}
2.package org.westos.demo0523;
/*Author:LH
CreatTime:2020.05.23.22:12*/
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class MyTest5 {
/*可以在方法声明上抛出异常
但是throws ParseException 就是在方法声明上抛出异常,如果字符串日期格式错误,
最终虚拟机会打印出错误信息,不会具体处理。*/
public static void main(String[] args) throws ParseException {
String date="2020-11-14";
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
Date parse = dateFormat.parse(date);
System.out.println(parse);
}
}
- Error:错误,严重性问题异常。
- 无法在代码中捕获处理。
Throwable父类和Exception,Error的关系
-
try catch关键字:
-
try{ 可能出现问题的代码}catch( 捕获何种类型的异常类名){你需要的处理逻辑}。如果没有捕获到异常代码,或者catch捕获的异常类信息不对,catch里面就不会执行。
-
多种异常捕获:
- try {
- 可能出现问题的代码 ;
- }catch(异常名1 变量名1){
- 对异常的处理方式 ;
- }catch (异常名2 变量名2){
- 对异常的处理方式 ;
- }…
- JDK1.7语法不一样,
- try {
- 可能出现问题的代码 ;
- }catch(异常名1 |异常名2|… ){
- 对异常的处理方式 ;
- }… 异常名只能是并列关系,不能是继承,处理逻辑也不能体现出具体的异常问题
-
不能分析出的异常:不能分析出的异常可以用最大的一场信息捕获(exception)
-
注意:
1.能明确的异常,尽量要明确。不要拿最大的异常捕获。对于后续的分析不利,不知道具体异常。
2.捕获的多个异常中有父子继承关系,父类异常放在后面。父类异常在前面后截取子类异常,子类异常就捕获不到了。
3.try里面放置有可能出现问题的代码,随便放置会影响性能。
-
-
异常处理常用的方法:
- 打印异常信息。
- 打印信息的方法: printStackTrace()方法
- 利用异常机制做一些逻辑处理。
- 打印异常信息。
-
运行期快速捕获异常的快捷键:Ctrl +Alt+t 或 直接在语句后面.try。
-
编译期的异常Alt+enter,捕获或者抛出
instanceof 关键字
- 作用是判断一个对象是否是一个类的实例
- instanceof:左边是对象,右边是类或者子类,当左边的对象是右边的类或者子类创建的对象,就返回true,否则返回false。
- 可以用在向下转型时判断一下。
finally 关键字
- 最终的,不管try里面的代码有没有异常,finally里面的代码都会执行。因此会在finally里面写一些善后收尾工作。例如:释放资源。释放空资源和正常释放资源
package org.westos.demo0523;
/*Author:LH
CreatTime:2020.05.23.21:17*/
public class MyTest3 {
public static void main(String[] args) {
try {
System.out.println(23 / 0);
} catch (Exception e) {
System.out.println("哦,catch了...............");
// return结束了主方法,但是不管try执行与否,finally都会被执行。但是下面的输出代码不被执行
return;
// System.exit(0); 如果是退出虚拟机,那么finally不会被执行。
// 不管try能不能捕捉到异常,finally都会执行
} finally {
System.out.println("哦,被执行了..............");
}
System.out.println("下面代码");
}
}
throw和throws的区别
- 相同点:都是异常的抛出
- 不同:
throw | throws | |
---|---|---|
1 | 在方法内部 | 在方法声明上 |
2 | 后面跟一个异常对象名 | 后面可以跟一个或多个异常类名,用逗号隔开 |
3 | 抛出异常,由方法体内部语句处理 | 表示抛出异常由调用者处理 |
4 | 执行了throw就一定发生 | 表示的一种可能性,有可能发生,也有可能不发生 |
自定义异常
-
在我们后面的编程中,可能会遇到Java没有提及的异常,但是我们业务需要,那就要自定义。
-
自定义异常抛出:
package org.westos.demo0523; /*Author:LH CreatTime:2020.05.23.15:41*/ import java.util.Scanner; public class MyException { public static void main(String[] args) { Scanner sc = new Scanner(System.in); System.out.println("请输入成绩"); int i= sc.nextInt(); if (i >= 0 && i <= 100) { System.out.println("输入正确"); } else { // 异常情况下,需要停止程序 throw new ScoreExcepiton(); } System.out.println(i); } } class ScoreExcepiton extends RuntimeException{ public ScoreExcepiton() { System.out.println("成绩不合法"); } } 2. package org.westos.demo0523; import java.util.Scanner; /*Author:LH CreatTime:2020.05.25.16:57*/ //当从银行取钱时,给出余额不足异常 public class MoneyTest { public static void main(String[] args) { int sum = 200; Scanner sc = new Scanner(System.in); System.out.println("请输入取款金额"); int i = sc.nextInt(); if (i > sum) { throw new MoneyException("余额不足"); } else { sum -= i; } System.out.println("存款余额" + sum); } } class MoneyException extends RuntimeException { public MoneyException(String s) { super(s); } }
继承关系类的异常抛出
- 子类重写父类方法时,如果父类方法没有抛出异常,子类也不能抛出异常
- 子类不能抛出父类没有抛出的异常。
- 子类抛出的异常只能小于等于父类。
- 父类方法有异常抛出,但是子类可以选择不抛出。
File类
- Java为了描述文件或者文件夹,提供了File类来描述文件或者路径名。
- 构造方法、方法
- 绝对路径和相对路径
- 绝对路径:带有盘符的详细路径
- 相对路径:不带有盘符号的路径(也是你项目的根目录下)
- 如果文件在项目的文件夹目录下,可以使用相对路径。
- . 或 . / 表示当前目录。…/上级路径。…/…/上两级目录。
- 创建文件或文件夹
- 创建文件: createNewFile(),创建文件。
- 创建文件夹
- mkdir:不好之处,只能创建单级文件夹。
- mkdirs:可以创建单级或者多级文件夹。所以直接使用这个方法。
- 文件或者文件夹存在,不重复创建。
- 删除文件或文件夹
- delete()方法:删除文件的时候,只能删除空文件夹,重复删除或者已经删除,返回false。
- deleteOnExit():在虚拟机退出时删除文件
- delete()方法只能删除非空目录。
- 重命名
- 重命名需要传递一个file类型的参数
- 重命名的原文件和传入文件不再同一个路径下,那就会原文件剪切并重命名。
- 原文件和传入的文件在相同路径下,就是重命名。
- 判断功能
- 判断是否是个文件:isFile()
- 判断是否是个目录:isDirectory()
- 判断文件/文件夹是否存在:exists()
- 判断文件是否可读:canRead()
- 判断文件是否可写:canWrite()
- 判断文件是否隐藏:isHidden()
- 获取方法
- 获取文件的绝对路径:getAbsoultePath(),返回字符串类型
- 获取文件的绝对路径:getAbsoulteFile(),返回File类型,更加灵活,可以直接调取File的方法。
- 获取相对路径:getPath(),返回字符串类型。
- 获取文件的父路径:getParent(),返回字符串类型
- 获取父路径:getParentFile(),返回File类型,更加灵活,可以直接调取File的方法。
- 在封装文件时使用相对路径,调此方法时就会返回null。
- 获取磁盘容量:getTotalSpace()
- 获取磁盘剩余容量:getFreeSpace()
- 获取文件名:getName()
- 获取文件的大小:length()
- 获取文件的最后一次修改时间:lastModified(),返回的是毫秒值。
- 获取指定目录下的文件或者文件夹的名称数组:list(),返回一个字符串数组。
- 获取指定目录下文件或者目录名的File类型数组:listFiles(),返回一个File类型的数组。
案例:
package org.westos.demo0523.File;
/*Author:LH
CreatTime:2020.05.25.17:45*/
import java.io.File;
import java.io.IOException;
//文件的创建
public class MyTest {
public static void main(String[] args) throws IOException {
// 文本文件的创建
File file = new File("a.txt");
// 此文件已经存在就返回false
boolean b = file.createNewFile();
System.out.println(b);
//获取文件名
System.out.println(file.getName());
// 对文件或者文件夹的删除。
// file.delete();
System.out.println("isFile()"+file.isFile());
System.out.println(file.getAbsolutePath());
System.out.println("canRead()"+file.canRead());
// 文件夹的创建
File file1 = new File("kkk\\lll\\nnn");
// 一般就是用多层文件夹的创建方法,也可以创建单级文件夹,所以比较通用
file1.mkdirs();
}
}
2.package org.westos.demo0523.File;
import java.io.File;
import java.util.Date;
/*Author:LH
CreatTime:2020.05.26.14:46*/
//file类的重命名功能
public class MyTest3 {
public static void main(String[] args) {
// 如果是相同路径下,就是重命名,不在同一个路径下就是复制到指定的路径下再命名。
File file = new File("a.txt");
File file1 = new File("b.txt");
boolean b = file.renameTo(file1);
System.out.println(b);
System.out.println(file1.getPath());
System.out.println("========");
// 当文件封装的是相对路径,那获取父类路径的file类对象就是null
System.out.println(file1.getParentFile());
System.out.println(file1.getAbsolutePath());
// 获取文件最后一次修改的时间。
long l = file1.lastModified();
Date date = new Date(l);
System.out.println(date);
}
}
3.package org.westos.demo0523.File;
/*Author:LH
CreatTime:2020.05.25.18:05*/
import java.io.File;
import java.io.IOException;
//异常的捕捉处理
public class MyTest2 {
public static void main(String[] args) {
// java允许我们实例化File时,可以传入多种样式路径。
//1.File(String parent, String child)
//2.File(String pathname)
//3.File(File parent, String child)
File file = new File("C:\\Users\\LH\\Desktop");
File file1 = new File(file, "a.txt");
//捕捉的快捷键Ctrl+ alt+T
try {
boolean newFile = file1.createNewFile();
System.out.println(newFile);
} catch (IOException e) {
e.printStackTrace();
}
}
}
4.package org.westos.demo0523.File;
import java.io.File;
import java.io.FileFilter;
import java.util.Arrays;
/*Author:LH
CreatTime:2020.05.26.15:54*/
//判断文件是否已指定后缀结尾
public class MyTest4 {
public static void main(String[] args) {
File file = new File("G:\\javase");
File[] listFiles = file.listFiles();
for (File listFile : listFiles) {
// 获取到文件名。然后判断是否已指定后缀结尾
boolean b = listFile.getName().endsWith(".pdf");
if (b) {
System.out.println(listFile.getName());
}
}
System.out.println("==========");
// 过滤指定好的文件,是先将封装好的文件调取listFiles方法的时候使用 FileFilter接口,将应包含在文件中的文件过滤出来
// 放在数组中,然后遍历获取。
File[] files = file.listFiles(new FileFilter() {
@Override
public boolean accept(File pathname) {
if (pathname.isFile()&&pathname.getName().endsWith(".pdf")) {
return true;
}else {
return false;
}
}
});
System.out.println(Arrays.toString(files));
for (File file1 : files) {
System.out.println(file1.getName());
}
}
}
5.
package org.westos.demo0524;
import java.io.File;
/*Author:LH
CreatTime:2020.05.25.9:41*/
//删除多级文件夹,delete只能删除空文件夹,因此使用递归将子文件夹清空,然后再删除父文件夹。
public class MyTest {
public static void main(String[] args) {
File file = new File("G:\\javatest");
delete(file);
}
private static void delete(File file) {
File[] files = file.listFiles();
for (File file1 : files) {
if (file1.isDirectory()) {
delete(file1);
} else {
file1.delete();
}
}
file.delete();
}
}
//使用递归将子文件夹清空,然后再删除父文件夹。
public class MyTest {
public static void main(String[] args) {
File file = new File("G:\\javatest");
delete(file);
}
private static void delete(File file) {
File[] files = file.listFiles();
for (File file1 : files) {
if (file1.isDirectory()) {
delete(file1);
} else {
file1.delete();
}
}
file.delete();
}
}