一,异常
定义:程序中一些处理不了的特殊情况
异常类 Exception 继ThrowAble
见过的异常 NullPointerException(空指针异常) ArrayIndexoutOfBoundsException(数组下标异常)
异常的分类:
1.检查型异常 (直接继承Exception),在编译时会抛出的异常(代码报错),需要在编译中编写处理方式(和程序之外的资源访问)
2.运行时异常(继承RuntimeException):在代码运行阶段可能会出现的异常,可以不用明文处理,可以通过代码避免异常的发生
public static void main(String[] args) {
String str=null;
// System.out.println(str.length());
String name="张三";
// boolean b=str.equals(name);
// b=name.equals(str);//避免空指针异常的发生
if(str!=null){
System.out.println(str);
}else{
System.out.println("str是null值");
}
int i=12;
int a=0;
if(a!=0){
System.out.println(i/a);
}else{
System.out.println("a==0不能做除数");
}
//处理文件
File file=new File("D:\\easy.text");
//检查性异常 编译异常
FileInputStream fis=null;
3.当程序中出现异常就会中断程序,代码不会继续运行
处理异常:1.try...catch...finally
try尝试捕捉异常 其中是可能会抛出异常的代码,是需要关闭的,通常写在finally块中.cloase()
catch:代码块中时捕捉到异常后要处理的代码,(用来捕获和处理try块抛出的异常,当try
块中抛出的异常与某个catch
块的参数类型相匹配时,这个catch
块就会执行,处理异常)
finally无论是否出现异常都会执行的代码块,一般用在关闭资源
ry{
//try尝试捕捉异常 其中是可能会抛出异常的代码
fis=new FileInputStream(file);//需要关闭
}catch(FileNotFoundException e){
//捕捉到异常后要处理的代码
e.printStackTrace();//打印异常日志
}finally{
//无论是否出现异常都会执行的代码块
//一般用在关闭资源
if (fis!=null){
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
try...catch处理多种异常
(1)出现几个异常就写几个catch去解决、
try{
System.out.println(12/0);
Object strA="";
System.out.println((Integer)strA);
fis=new FileInputStream(file);
} catch (ArithmeticException e){
//出现数学运算异常ArithmeticException要执行的代码
System.out.println("出现ArithmeticException");
}catch(ClassCastException e){
System.out.println("出现");
}catch(FileNotFoundException e){
System.out.println("出现");
}finally {
if(fis!=null){
try{
fis.close();
}catch(IOException e){
e.printStackTrace();
}
}
}
(2)catch合并处理方案 一个catch处理多种异常(使用 | 声明多种异常)
try{
System.out.println(12/0);
Object strA="";
System.out.println((Integer)strA);
fis=new FileInputStream(file);
}catch (ArithmeticException|ClassCastException|FileNotFoundException e){
}
(3)catch块声明父类异常,捕捉所有子类异常
try{
System.out.println(12/0);
Object strA="";
System.out.println((Integer)strA);
fis=new FileInputStream(file);
}catch (Exception e){
}
(4)catch异常捕捉的顺序 子类异常优先处理,父类异常后置处理
try{
List list=new ArrayList();//声明一个集合
list.remove(8);//Indexout
int[] arr=new int[2];
arr[8]=22;//ArrayIndex
String strA="abc";
strA.charAt(8);//StringIndex
}catch (ArrayIndexOutOfBoundsException e){
e.printStackTrace();
}
catch (IndexOutOfBoundsException e){
e.printStackTrace();
}
System.out.println(test());
}
(5)如果catch出现抛出了异常,没有finally就会中断程序
如果有finally,就会运行finally 并且正常返回,此方法正常运行结束
public static int test(){
try{
System.out.println(12/0);
return 1;
}catch(Exception e){
throw new Exception();
// return 2;
}finally {
System.out.println(12/0);
return 3;
}
}
(6)注意点:try不能单独编写·,必须有其他语句块
try块例没有检查型异常时,不能在catch块中随意捕捉
只有try和fianlly时不能出现检查型异常
public static void testA(){
// try{
// System.out.println(12/0);
// }catch (Exception e){
//
// }
//try块里面没有检查型异常时,不能在catch块中随意捕捉
FileInputStream fis=null;
File file=null;
try {
System.out.println(12/0);
//只有try和finally时不能出现检查型异常
// fis=new FileInputStream(file);
}finally {
}
二.自定义异常
定义自定义异常,可以在代码块中使用它来抛出和捕获异常
throw是抛出,用于抛出异常,它立即停止当前方法的执行,并将控制权转移到最近的catch
块。
public void infoA(){
if(name==null){
throw new NullPointerException("name is null");
//运行时异常不需要throws强调声明
// throw new RuntimeException("具体说明");
// throws new Exception();
}
throw
后面跟着一个异常对象,通常是通过调用异常类的构造函数创建的。
throws是声明,用于声明方法可能抛出的异常,它不抛出异常,而是告知调用者需要处理这些异常。
public void info() throws StudentNmaeIsNullException,NullPointerException,IndexOutOfBoundsException{//抛出多种异常
//name=null是一种特殊情况 不符合业务需求
if(name==null){
throw new StudentNmaeIsNullException("student name is null");
}
System.out.println("我的名字"+name);
}
throws
关键字放在方法签名的括号后面,紧接着是一系列可能抛出的异常类型列表。
子类继承父类,方法重写:子类对父类继承过来的方法进行重新定义
约束:返回值 方法名 参数里表都不能改变
访问权限只能更开放,抛出的异常只能更精确,范围更小,不能扩大
运行时异常不需要throws强调声明
总结:
三,文件
java中对文件 java.io java.lang java.util
(1)声明一个文件
File f=new File("D:\\easy.txt");
(2)是否存在该文件,用exists();
//是否存在该文件
boolean bool=f.exists();
System.out.println(bool);
(3)验证是否是文件,用isFile();
//验证是否是文件
bool=f.isFile();
System.out.println(bool);
(4)是否是文件夹 isDirectory()
//是否是文件夹
bool=f.isDirectory();
System.out.println(bool);
(5)创建文件,删除文件
先判断文件是否存在,如果不存在就创建一个新文件,如果存在就删除
注意:删除文件夹时,文件夹必须是空文件夹
//创建文件
if (!bool){
try{
bool=f.createNewFile();
if(bool){
System.out.println("成功创建文件");
}
}catch (IOException e){
e.printStackTrace();
}
}else{
//删除文件夹时,文件夹必须是空的文件夹
f.delete();
System.out.println("成功删除文件");
}
(6) mkdirs()
会尝试创建从根目录开始到指定目录的所有缺失目录
mkdir()
是Java中java.io.File
类的一个方法,用于创建一个由File
对象表示的目录(文件夹)。如果指定的目录不存在,并且该目录的父目录已经存在,那么mkdir()
方法将创建这个目录。
四,IO流
IO 输入流/输出流,流动的是数据 二进制
分类:(1)根据流动的方向不同 分为输入流和输出流
(2)根据流动的介质(单位)不同分为 字符流和字节流
字符流只能读取 txt .xml .properties .html .yml
字节流可以读取任意的文件类型
(3)根据功能不同分为节点流和工具流 打印流 数据流 对象流
1.定义字节输入/输出流 字符输入/输出流
public static void main(String[] args) {
//字节输入流
InputStream is;
//字节输出流
OutputStream os;
//字符输入流
Reader r;
//字符输出流
Writer w;
2.读入文件 字节输入流
首先创建一个字节输入流 fis 读取txt文件,创建一个数组临时存储文件中的数据,并利用while循环将从文件中读取到的数据一个一个的转换为字符串并打印出来,并检查处理读取文件时可能发生的异常
public static void readFile(){
FileInputStream fis=null;
try{
fis=new FileInputStream("D:\\easy.txt");
byte[] arr=new byte[16];
//读取多少就转换多少
int length=0;
while ((length=fis.read(arr))!=-1){
//arr 中就是读取到的数据
String str=new String(arr,0,length);
System.out.print(str);
// String.valueOf(arr);
}
}catch (IOException e){
e.printStackTrace();
}finally {
if (fis!=null) {
try{
fis.close();
}catch(IOException e){
e.printStackTrace();
}
}
}
}
3.读入文件 缓冲流 字符流
首先创建fis输入流读取文件,创建isr转换流将字节流转换为字符流,创建br读取文件的一行内容
public static void readFileBuffer() {
// 文件字节输入流
FileInputStream fis = null;
// 转换流,将字节流转换为字符流
InputStreamReader isr = null;
// 缓冲流,用于提高读取效率,特别适合文本文件的读取
BufferedReader br = null;
try {
// 创建FileInputStream,用于读取"D:\easy.txt"文件
fis = new FileInputStream("D:\\easy.txt");
// 创建InputStreamReader,将FileInputStream包装为字符流
// 使用系统默认的字符集进行解码
isr = new InputStreamReader(fis);
// 创建BufferedReader,进一步包装InputStreamReader
// 提供了readLine()方法用于按行读取文本
br = new BufferedReader(isr);
// 使用readLine()方法读取文件的一行内容
// 如果文件中还有更多行,readLine()将继续读取下一行
// 如果到达文件末尾,readLine()将返回null
String line = br.readLine();
// 打印读取到的第一行文本到控制台
System.out.println(line);
} catch (IOException e) {
// 捕获任何可能在读取文件时发生的IOException
// IOException可能发生在FileInputStream、InputStreamReader或BufferedReader的任何阶段
e.printStackTrace();
} finally {
// 无论是否发生异常,都尝试关闭FileInputStream
// 这里只关闭了fis,但更佳的做法是关闭最外层的流,即br
// 因为BufferedReader和InputStreamReader在关闭时会自动关闭它们所包装的流
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
// 如果在关闭流时发生IOException,打印异常堆栈
e.printStackTrace();
}
}
}
}
4. 向文件中写入文本内容 字节输出流 fos
定义要写入文件的字符串,将字符串转换为字节数组并声明FileOutputStream变量对象 fos 字符输出流,用于向文件中写入内容
public static void writeFile() {
// 定义要写入文件的字符串
String str = "吃饭吃饭";
// 将字符串转换为字节数组,使用系统的默认字符集编码
byte[] arr = str.getBytes();
// 声明FileOutputStream变量,用于写入文件
FileOutputStream fos = null;
try {
// 创建FileOutputStream实例,用于写入"D:\easy.txt"文件
// 第二个参数设置为true表示追加模式,如果文件已存在,新的内容将被添加到文件末尾
fos = new FileOutputStream("D:\\easy.txt", true);
// 使用fos.write(arr)将字节数组写入文件
// 这将把arr中的所有字节写入文件
fos.write(arr);
} catch (IOException e) {
// 捕获并处理可能在写入文件时发生的任何IOException
// 这可能包括文件不可写、磁盘满等情况
e.printStackTrace();
} finally {
// 无论是否发生异常,都尝试关闭FileOutputStream
if (fos != null) {
try {
// 关闭流以释放系统资源
fos.close();
} catch (IOException e) {
// 如果在关闭流时发生IOException,打印异常堆栈
e.printStackTrace();
}
}
}
}
5.序列化
将内存对象转换成序列(字节流)的过程叫做序列化
将一个对象序列化并写入文件:
创建Staff
package com.easy723;
import java.io.Serializable;
public class Staff implements Serializable {
String name;
String sex;
int salary;
@Override
public String toString() {
return "Staff{" +
"name='" + name + '\'' +
", sex='" + sex + '\'' +
", salary=" + salary +
'}';
}
}
public static void writeObject() {
// 创建Staff对象,这个对象需要实现Serializable接口才能被序列化
Staff staff = new Staff();
staff.name = "张三"; // 设置Staff对象的属性
staff.sex = "男";
staff.salary = 3500;
// ObjectOutputStream用于将对象写入文件
ObjectOutputStream oos = null;
// FileOutputStream用于创建文件输出流
FileOutputStream fos = null;
try {
// 创建FileOutputStream,用于写入"D:\easy.txt"文件
fos = new FileOutputStream("D:\\easy.txt");
// 使用FileOutputStream创建ObjectOutputStream
oos = new ObjectOutputStream(fos);
// 使用oos.writeObject()将staff对象写入文件
// 这个方法会将对象的状态转换为字节流并写入文件
oos.writeObject(staff);
} catch (IOException e) {
// 捕获并处理可能在序列化或写入文件时发生的任何IOException
// 这可能包括文件不可写、磁盘满、对象不可序列化等情况
e.printStackTrace();
} finally {
// 无论是否发生异常,都尝试关闭ObjectOutputStream和FileOutputStream
if (oos != null) {
try {
// 关闭ObjectOutputStream,它会自动关闭内部的FileOutputStream
oos.close();
} catch (IOException e) {
// 如果在关闭流时发生IOException,打印异常堆栈
e.printStackTrace();
}
}
if (fos != null) {
try {
// 这里的fos.close()实际上是冗余的,因为oos.close()已经完成了这个操作
// 不过,为了清晰展示,保留了fos的关闭逻辑
fos.close();
} catch (IOException e) {
// 如果在关闭流时发生IOException,打印异常堆栈
e.printStackTrace()
6.反序列化 :将对象序列(字节流)读入程序,转换成对象的方式
反序列化会创建新的对象
public static void readObject() {
// FileInputStream用于读取文件中的字节流
FileInputStream fis = null;
// ObjectInputStream用于从字节流中读取序列化的对象
ObjectInputStream ois = null;
try {
// 创建FileInputStream,用于读取"D:\easy.txt"文件
fis = new FileInputStream("D:\\easy.txt");
// 使用FileInputStream创建ObjectInputStream,用于读取序列化的对象
ois = new ObjectInputStream(fis);
// 使用ois.readObject()从文件中读取一个序列化的对象
// 这个方法返回Object类型,因此需要向下转型为具体的类型才能使用
Object obj = ois.readObject();
// 打印读取到的对象,通常这里会输出对象的toString()方法的返回值
// 或者对象的类型和引用地址
System.out.println(obj);
} catch (Exception e) {
// 捕获并处理可能在反序列化或读取文件时发生的任何异常
// 这里使用了泛型的Exception,但更具体的应捕获IOException和ClassNotFoundException
// IOException可能在读取文件或反序列化时发生
// ClassNotFoundException可能在反序列化时,如果对象的类在运行环境中不存在
e.printStackTrace();
} finally {
// 无论是否发生异常,都尝试关闭ObjectInputStream和FileInputStream
if (ois != null) {
try {
// 关闭ObjectInputStream,它会自动关闭内部的FileInputStream
ois.close();
} catch (IOException e) {
// 如果在关闭流时发生IOException,打印异常堆栈
e.printStackTrace();
}
}
if (fis != null) {
try {
// 这里的fis.close()实际上是冗余的,因为ois.close()已经完成了这个操作
// 不过,为了清晰展示,保留了fis的关闭逻辑
fis.close();
} catch (IOException e) {
// 如果在关闭流时发生IOException,打印异常堆栈
e.printStackTrace();
}
}
}
}
总结:创建对象的方式
1.new 2.克隆 3.反序列化 4.反射