异常就是程序出现的不正常的情况。
1.异常的体系
Throwable
|--Error严重问题,我们不处理。|--Exception
|--RuntimeException运行期异常,我们需要修正代码|--非RuntimeException 编译期异常,必须处理的,否则程序编译不通过
2.异常的处理
1)JVM的默认处理
把异常的名称,原因,位置等信息输出在控制台,但是呢程序不能继续执行了。
2)自己处理
A:try...catch...finally: 自己编写处理代码,后面的程序可以继续执行B:throws: 把自己处理不了的,在方法上声明,告诉调用者,这里有问题
3.自定义异常
继承自Exception或者RuntimeException,只需要提供无参构造和一个带参构造即可
4.异常的注意点
1)父的方法有异常抛出,子的重写方法在抛出异常的时候必须要小于等于父的异常2)父的方法没有异常抛出,子的重写方法不能有异常抛出3)父的方法抛出多个异常,子的重写方法必须比父少或者小4)编译期异常和运行期异常的区别?
编译期异常 必须要处理的,否则编译不通过运行期异常 可以不处理,也可以处理
5)throw和throws是的区别
throw:在方法体中,后面跟的是异常对象名,并且只能是一个throw抛出的是一个异常对象,说明这里肯定有一个异常产生了throws:在方法声明上,后面跟的是异常的类名,可以是多个throws是声明方法有异常,是一种可能性,这个异常并不一定会产生
5.finally关键字
1)finally用于释放资源,它的代码永远会执行。特殊情况:在执行到finally之前jvm退出了2) final,finally,finalize的区别:
A:final,修饰符(关键字)
如果一个类被声明为final,意味着它不能再派生出新的子类,不能作为父类被继承。将变量或方法声明为final,可以保证它们在使用中不被改变。被声明为final的方法只能使用,不能重载。
B:finally,再异常处理时提供 finally 块来执行任何清除操作。如果抛出一个异常,那么相匹配的 catch 子句就会执行,然后控制就会进入 finally 块(如果有的话)。C:finalize,方法名。finalize() 方法在垃圾收集器将对象从内存中清除出去之前做必要的清理工作。由垃圾收集器在确定这个对象没有被引用时对这个对象调用的。
3)如果在catch里面有return,finally还仍然执行,并且是在return中间执行的 。
首先return时把要return的值先处理好,然后再执行finally里的代码,执行后再将缓存好的要return的值返回
二、File
IO流操作中大部分都是对文件的操作,所以Java就提供了File类供我们来操作文件
1.构造方法
1)File file = new File("e:\\demo\\a.txt"); 根据一个路径得到File对象2)File file = new File("e:\\demo","a.txt"); 根据一个目录和一个子文件/目录得到File对象3)File file3 = new File("e:\\demo"); 根据一个目录得到File对象(文件夹)4) File file = new File(file,"a.txt"); 根据一个父File对象和一个子文件/目录得到File对象
2.File类的功能
1)创建功能:
public boolean createNewFile():创建文件 如果存在这样的文件,就不创建了public boolean mkdir():创建文件夹 如果存在这样的文件夹,就不创建了public boolean mkdirs():创建文件夹,如果父文件夹不存在,会帮你创建出来
2)删除功能: public boolean delete()
3)重命名功能:public boolean renameTo(File dest)
如果路径名相同,就是改名。如果路径名不同,就是改名并剪切。
4)判断功能:
public boolean isDirectory():判断是否是目录public boolean isFile():判断是否是文件public boolean exists():判断是否存在public boolean canRead():判断是否可读public boolean canWrite():判断是否可写public boolean isHidden():判断是否隐藏
5)获取功能:
public String getAbsolutePath():获取绝对路径public String getPath():获取相对路径public String getName():获取名称public long length():获取长度。字节数public long lastModified():获取最后一次的修改时间,毫秒值
6)高级获取功能:
public String[] list():获取指定目录下的所有文件或者文件夹的名称数组public File[] listFiles():获取指定目录下的所有文件或者文件夹的File数组
7)过滤器功能:
public String[] list(FilenameFilter filter)public File[] listFiles(FilenameFilter filter)
3.案例:
输出指定目录下指定后缀名的文件名称
import java.io.File; import java.io.FilenameFilter; /* * 判断E盘目录下是否有后缀名为.jpg的文件,如果有,就输出此文件名称 * A:先获取所有的,然后遍历的时候,依次判断,如果满足条件就输出。 * B:获取的时候就已经是满足条件的了,然后输出即可。 * * 要想实现这个效果,就必须学习一个接口:文件名称过滤器 * public String[] list(FilenameFilter filter) * public File[] listFiles(FilenameFilter filter) */ public class FileDemo2 { public static void main(String[] args) { // 封装e判断目录 File file = new File("e:\\"); // 获取该目录下所有文件或者文件夹的String数组 // public String[] list(FilenameFilter filter) String[] strArray = file.list(new FilenameFilter() { @Override public boolean accept(File dir, String name) { // return false; // return true; // 通过这个测试,我们就知道了,到底把这个文件或者文件夹的名称加不加到数组中,取决于这里的返回值是true还是false // 所以,这个的true或者false应该是我们通过某种判断得到的 // System.out.println(dir + "---" + name); // File file = new File(dir, name); // // System.out.println(file); // boolean flag = file.isFile(); // boolean flag2 = name.endsWith(".jpg"); // return flag && flag2; return new File(dir, name).isFile() && name.endsWith(".jpg"); } }); // 遍历 for (String s : strArray) { System.out.println(s); } } }
三、递归
方法定义中调用方法本身的现象叫做递归
1.递归的注意事项;
1)要有出口,否则就是死递归2)次数不能过多,否则内存溢出3)构造方法不能递归使用
四、IO流概述与字节流
2.递归的案例:
递归输出指定目录下所有指定后缀名的文件绝对路径
import java.io.File; /* * 需求:请大家把E:\JavaSE目录下所有的java结尾的文件的绝对路径给输出在控制台。 * * 分析: * A:封装目录 * B:获取该目录下所有的文件或者文件夹的File数组 * C:遍历该File数组,得到每一个File对象 * D:判断该File对象是否是文件夹 * 是:回到B * 否:继续判断是否以.java结尾 * 是:就输出该文件的绝对路径 * 否:不搭理它 */ public class FilePathDemo { public static void main(String[] args) { // 封装目录 File srcFolder = new File("E:\\JavaSE"); // 递归功能实现 getAllJavaFilePaths(srcFolder); } private static void getAllJavaFilePaths(File srcFolder) { // 获取该目录下所有的文件或者文件夹的File数组 File[] fileArray = srcFolder.listFiles(); // 遍历该File数组,得到每一个File对象 for (File file : fileArray) { // 判断该File对象是否是文件夹 if (file.isDirectory()) { getAllJavaFilePaths(file); } else { // 继续判断是否以.java结尾 if (file.getName().endsWith(".java")) { // 就输出该文件的绝对路径 System.out.println(file.getAbsolutePath()); } } } } }
IO用于在设备间进行数据传输的操作
1.分类:
1)流向
输入流 读取数据
输出流 写出数据
2)数据类型
字节流
字节输入流
字节输出流
字符流
字符输入流
字符输出流
3)注意:
A:如果没有明确说明按照什么分,默认按照数据类型分。
B:除非文件用记事本打开能够读懂,才采用字符流,否则建议使用字节流。
2.FileOutputStream写出数据
1)构造方法:
FileOutputStream(File file)
FileOutputStream(String name)
FileOutputStream(String name, boolean append);
1)操作步骤
A:创建字节输出流对象
B:调用write()方法
C:释放资源
2)代码体现:
FileOutputStream fos = new FileOutputStream("fos.txt"); fos.write("hello".getBytes()); fos.close();
3)注意
A:创建字节输出流对象所做的事情
a:调用系统功能去创建文件
b:创建fos对象
b:把fos对象指向这个文件
B:close()的作用:释放资源
a:让流对象变成垃圾,这样就可以被垃圾回收器回收了
b:通知系统去释放跟该文件相关的资源
C:实现数据的换行方式:
写入换行符号:
windows:\r\n
linux:\n
Mac:\r
D:实现数据的追加写入的方式:用构造方法带第二个参数是true的情况即可
4)案例
public class FileOutputStreamDemo3 { public static void main(String[] args) throws IOException { // 创建字节输出流对象 // FileOutputStream fos = new FileOutputStream("fos3.txt"); // 创建一个向具有指定 name 的文件中写入数据的输出文件流。如果第二个参数为 true,则将字节写入文件末尾处,而不是写入文件开始处 FileOutputStream fos = new FileOutputStream("fos3.txt", true); // 写数据 for (int x = 0; x < 10; x++) { fos.write(("hello" + x).getBytes()); fos.write("\r\n".getBytes()); } // 释放资源 fos.close(); } }
3.FileInputStream读取数据
1)构造方法:
FileInputStream(String name)
2)操作步骤
A:创建字节输入流对象
B:调用read()方法
C:释放资源
3)代码体现:
FileInputStream fis = new FileInputStream("fos.txt"); // 方式1 int by = 0; while ((by = fis.read()) != -1) { System.out.print((char) by); } // 方式2 byte[] bys = new byte[1024]; int len = 0; while ((len = fis.read(bys)) != -1) { System.out.print(new String(bys, 0, len)); } fis.close();
4.字节缓冲区流
java开始在设计的时候,考虑到了一次读一个字节速度很慢,就专门提供了带缓冲区的字节类。
这种类被称为:缓冲区类(高效类)
构造方法可以指定缓冲区的大小,但是我们一般用不上,因为默认缓冲区大小就足够了
1)BufferedOutputStream:写数据
构造方法:BufferedInputStream(InputStream in)
2)BufferedInputStream:读数据
构造方法:BufferedOutputStream(OutputStream out)
5.案例
package cn.itcast_06; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; /* * 需求:把e:\\test.mp4复制到当前项目目录下的copy.mp4中 * * 字节流四种方式复制文件: * 基本字节流一次读写一个字节: 共耗时:117000毫秒 * 基本字节流一次读写一个字节数组: 共耗时:150毫秒 * 高效字节流一次读写一个字节: 共耗时:1100毫秒 * 高效字节流一次读写一个字节数组: 共耗时:40毫秒 */ public class CopyMp4Demo { public static void main(String[] args) throws IOException { long start = System.currentTimeMillis(); // method1("e:\\test.mp4", "copy1.mp4"); // method2("e:\\test.mp4", "copy2.mp4"); // method3("e:\\test.mp4", "copy3.mp4"); method4("e:\\test.mp4", "copy4.mp4"); long end = System.currentTimeMillis(); System.out.println("共耗时:" + (end - start) + "毫秒"); } // 高效字节流一次读写一个字节数组: public static void method4(String srcString, String destString) throws IOException { BufferedInputStream bis = new BufferedInputStream(new FileInputStream( srcString)); BufferedOutputStream bos = new BufferedOutputStream( new FileOutputStream(destString)); byte[] bys = new byte[1024]; int len = 0; while ((len = bis.read(bys)) != -1) { bos.write(bys, 0, len); } bos.close(); bis.close(); } // 高效字节流一次读写一个字节: public static void method3(String srcString, String destString) throws IOException { BufferedInputStream bis = new BufferedInputStream(new FileInputStream( srcString)); BufferedOutputStream bos = new BufferedOutputStream( new FileOutputStream(destString)); int by = 0; while ((by = bis.read()) != -1) { bos.write(by); } bos.close(); bis.close(); } // 基本字节流一次读写一个字节数组 public static void method2(String srcString, String destString) throws IOException { FileInputStream fis = new FileInputStream(srcString); FileOutputStream fos = new FileOutputStream(destString); byte[] bys = new byte[1024]; int len = 0; while ((len = fis.read(bys)) != -1) { fos.write(bys, 0, len); } fos.close(); fis.close(); } // 基本字节流一次读写一个字节 public static void method1(String srcString, String destString) throws IOException { FileInputStream fis = new FileInputStream(srcString); FileOutputStream fos = new FileOutputStream(destString); int by = 0; while ((by = fis.read()) != -1) { fos.write(by); } fos.close(); fis.close(); } }