Java笔记异常与IO流

异常与IO流

异常:Exception   arr

定义:

     程序运行过程中出现的一些预料之外的情况
     程序出现异常后,其之后代码不会执行,程序中断

怎么抛出异常:

     throws 在定义方法时 声明方法中可能会抛出的异常
     throw  在方法中特定抢矿下抛出一个具体的异常
  

怎么处理异常:

 使用 try…catch…finally… -------- 作用:增加程序健壮性

注:无论是否捕捉到异常  finally都会运行

怎么处理多种异常:

        分开处理
        总和处理:
            |
            Exception

打印异常:

            

常见的异常:

空指针异常(NullPointerException):
当试图访问或操作一个null对象时引发。例如,使用一个未初始化的对象引用获取其属性或方法时,就会抛出此异常。
数组下标越界异常(ArrayIndexOutOfBoundsException):
     这种异常通常发生在试图访问数组的长度范围之外的索引时就会触发此异常。
字符串下标越界(StringIndexOutOfBoundsException):
这种异常通常发生在试图访问字符串的长度范围之外的索引时就会触发此异常
数学运算异常(ArithmeticException):
这种异常通常发生在执行非法的数学运算时,例如除以零。
类型转换异常(ClassCastException):
它在进行强制类型转换时出现错误。
数字转换异常(NumberFormatException):

通常发生在将一个数据类型转换为另一个数据类型时,如果两者之间存在不兼容的情况。例如,当我们试图将一个字符串转换为数字类型时,Java会根据字符串的内容来判断其是否符合数字格式。

异常的结构:

     Throwable:
---Error
---Exception
     ----直接子类            检查型异常
     ----RuntimeException    运行时异常

异常的分类:

运行时异常:
继承RuntimeException或其子类
不需要在代码中明文处理
可以通过代码规避
不需要使用throws关键字声明方法运行可能抛出的异常
检查型异常(编译时异常):
继承Exception,但不是RuntimeException的子类
必须明文处理的异常,如果不处理编译时代码报错
检查型异常多数和程序之外的资源交互 不能通过代码规避
如果方法中抛出检查型异常,必须明文声明throws异常类型

定义异常:

   异常的类名-----体现出异常的作用/何时抛出异常
   声明:继承   检查/运行时异常      构造方法(两个)
 
 
问:什么是检查型异常?什么是运行时异常?它们的区别?
答:
     检查型异常(Checked Exception):
这类异常在编译时就会被检查,需要在代码中进行处理,否则编译器会报错。检查型异常通常是由外部因素引起的,例如文件不存在、网络连接中断等。常见的检查型异常有IOExceptionSQLException等。
 
运行时异常(Runtime Exception):
这类异常在编译时不会被检查,只有在程序运行过程中才会抛出。运行时异常通常是由程序内部的逻辑错误引起的,例如数组越界、空指针异常等。常见的运行时异常有NullPointerExceptionArrayIndexOutOfBoundsException等。
 
它们的区别主要有以下几点:
检查型异常需要在使用前进行捕获或者声明抛出,而运行时异常不需要。
检查型异常通常是由外部因素引起的,而运行时异常是由程序内部的逻辑错误引起的。
 
问:异常的继承结构?
答:
Throwable:是Java中所有异常和错误的超类。它有两个子类:ErrorException
----Error:表示程序无法处理的严重问题,如系统崩溃、虚拟机错误等。
----Exception:表示程序可以处理的异常情况,如文件未找到、空指针异常等。这些异常需要在代码中进行处理。
Exception又分为两个主要分支:
-----检查型异常(Checked Exception):这类异常在编译时就会被检查,需要在代码中进行处理,否则编译器会报错。
-----运行时异常(Runtime Exception):这类异常在编译时不会被检查,只有在程序运行过程中才会抛出。运行时异常通常是由程序内部的逻辑错误引起的,如数组越界、空指针异常等。

问:常见的异常有哪些?
答:
    空指针异常(NullPointerException):
这种异常通常是由于试图访问或操作一个null对象时引发的。
非法访问错误(IllegalAccessError):
这种异常发生在当一个应用试图访问、修改某个类的域(Field)或者调用其方法,但是又违反域或方法的可见性规定时。
数组下标越界异常(ArrayIndexOutOfBoundsException)
这是一种运行时异常,常常由数组索引超出范围引起。
算术异常(ArithmeticException):
比如除以零等。
类未找到异常(ClassNotFoundException):
Java虚拟机或者类加载器试图找到一个本地类型,但没有找到时,就会抛出这个异常。
文件未找到异常(FileNotFoundException):
当试图打开的文件不存在时,就会抛出这个异常。
输入/输出异常(IOException):
如读写文件出现问题时。
NoSuchMethodErrorNoClassDefFoundError
分别是方法未找到错误和类未找到错误,通常发生在JVM或者class文件中找不到指定的方法或类。
运行时异常(RuntimeException):
包括空指针异常,算术异常,数组越界异常等。
 
问:throwthrows的区别?
答:
   throw用于方法内部,表示手动抛出一个异常对象。它后面必须紧跟着一个异常类或其子类的实例对象。
   

   throws用于方法声明时,表示该方法可能会抛出某种异常,但具体异常对象由调用者来处理。它后面跟的是异常类名,不需要跟具体的异常对象。
  

综上:
throw用于方法内部抛出异常,而throws用于方法声明可能抛出的异常。throw后面跟具体的异常对象,而throws后面跟的是异常类名。
 
问:java是怎么处理异常的/Java处理异常的机制/你对异常的理解
     回答方向:什么是异常
         怎么处理
         怎么定义异常/怎么抛出异常
 答:
首先,什么是异常?
Java中的异常是程序在运行过程中出现的错误或问题,它会导致程序的流程被中断或者无法继续执行下去。
Java中的异常都是通过类来表示的,这些类都继承自Throwable类。Throwable类有两个子类:ErrorException
Error表示程序无法处理的严重问题,如系统崩溃、虚拟机错误等;
Exception表示程序可以处理的异常情况,如文件未找到、空指针异常等。
然后,怎么处理异常/怎么抛出异常?
Java提供了try-catch-finally语句来处理异常。当程序执行到可能抛出异常的代码时,将其放在try块中;如果try块中的代码抛出了异常,那么与之对应的catch块将会捕获这个异常并进行处理;无论是否发生异常,finally块中的代码都会被执行。
抛出异常的方法是使用throw关键字,后面跟一个异常对象。可以在方法内部抛出异常,也可以在方法声明时使用throws关键字声明可能抛出的异常。
最后,怎么定义异常
Java中,可以通过继承Exception类或其子类来自定义异常。自定义异常需要使用关键字extends

IO流:

文件对象:

     File: 

判断文件是否存在:
     

创建文件:
     

删除文件:
     

创建文件夹:
     

判断是不是文件夹:
     

 删除文件夹:
     

获取文件夹中的文件:
      

 递归删除文件:

复制文件:

输入流/输出流:

InputStream类:
输入流用于从外部源(如文件、网络连接等)读取数据。它的主要子类有: FileInputStream

ByteArrayInutStream

BufferedInputStream

DataInputStream

ObjectInputStream
OutputStream类:
输出流用于将数据写入到外部目标(如文件、网络连接等)。它的主要子类有: 
FileOutputStream

ByteArrayOutputStream
BufferedOutputStream

DataOutputStream

ObjectOutputStream

PrintStream
 
Reader类:
FileReader

BufferedReader
InputStreamReader
Reader 用于读取的字符流抽象类,数据单位为字符。
 
Writer类:
FileWriter
BufferedWriter
OutputStreamWriter

Writer 用于输出的字符流抽象类,数据单位为字符。

 
流的分类
按流的方向分类:

输入流:数据源到程序(InputStream、Reader 读进来)。

输出流:程序到目的地(OutPutStream、Writer 写出去)。

按流的处理数据单元分类:

字节流:按照字节读取数据(InputStream、OutputStream)。

字符流:按照字符读取数据(Reader、Writer)。

按流的功能分类:

节点流:可以直接从数据源或目的地读写数据。

FileReade----文件读取
FileWrite-----文件写出

处理流:不直接连接到数据源或目的地,是处理流的流。通过对其他流的处理提高程序的性能。

常用流的描述

文件字节流:以字节的形式读写文件

文件字符流:以字符的形式读写文件

缓冲字节流:为字节流增加缓冲,提高文件的读取速度

字节数组流:读写内容,返回byte[]数组

数据流:对文件读写各种类型的数据

转换流:字节流与字符流之间的转换,主要是字节流转为字符流

对象流:对文件进行对象的读写

ObjectOutputStearm

ObjectInputStearm

IO流相关类

四大基本抽象类InputStream、OutputStream、Reader、Writer

缓冲流Buffer:
 输入缓冲流:

BuffererRead     RedLine()

 输出缓冲流:

提供一个8192大小的数组临时存放数据

   BufferWriter:

   每次执行write方法写出的数据并没有直接写出,而是临时存进数组中

  1. 当数组中的空间存不下要写出的数据,BufferedWrite会将数组中的数据写出
  2. 要存储的数据没有8192大,写出数组中原来存储的数据,然后将A存到数组
  3. 要存储的数据比8192大,会先把数组中的数据写出,然后将A写出

                  

  注意:执行完成后要手动执行flush方法
 
 

系列化/反序列化:

把 Java 对象转换为字节序列的过程称为对象的序列化。把字节序列恢复为 Java 对象的过程称为对象的反序列化。

ObjectOutputStream 代表对象输出流,它的 writeObject(Object obj)方法可对参数指定的obj 对象进行序列化,把得到的字节序列写到一个目标输出流中。

ObjectInputStream 代表对象输入流,它的 readObject()方法从一个源输入流中读取字节序列,再把它们反序列化为一个对象,并将其返回。

只有实现了 Serializable 接口的类的对象才能被序列化。Serializable 接口是一个空接口,只起到标记作用。

对象流:

ObjectOutputStream/ ObjectInputStream

注意:

想要序列化必须实现Serializable接口  

序列化出去的对象和反序列化的对象不是同一个对象

       反序列化会创建新的对象

使用常量serialVersionUID控制类型的序列化版本,如果该值发生变化,之前序列化出去的对象(数据),不能反序列化回来。

序列化对象:这个对象的属性以及保存(数组中)的数据也必须是可序列化

避免对象属性被序列化/反序列化(transient):

面试常问:

  1. 什么是序列化/反序列化?

答:

序列化是将对象的状态信息转换为可以存储或传输的二进制序列的过程。

反序列化则是将字节流转换回对象的过程。

  1. 为什么要实现序列化/反序列化?

答:

因为Java对象是运行在JVM的堆内存中的,如果JVM停止后,这些对象也就无法继续存在。但有时我们需要在JVM停止后,把这些对象保存到磁盘或者传输到另一远程机器,由于计算机并不认识Java对象,它们只认识二进制这些机器语言,所以我们需要把对象转化为字节数组,也就是序列化。

反序列化就是将这个字节数组转换为Java对象交给JVM去运行。

  1. 怎样实现序列化/反序列化?

答:

要实现Java对象的序列化和反序列化,首先需要让对象实现Serializable接口。这个接口是一个标记接口,没有任何方法需要实现。当一个类实现了Serializable接口时,它的实例可以被序列化和反序列化。

  1. 序列化需要注意什么?/你对序列化的理解?/谈谈Java的序列化?

答:

Java序列化是将Java对象转换为字节序列的过程,这样我们就可以将对象保存到磁盘上,通过网络进行传输,或者存储在内存中,以后再进行反序列化时,将字节流重新转换为对象。

序列化和反序列化是相互对应的。反序列化则是打开我们之前序列化得到的特殊文件(字节序列),读取序列化的数据,然后将其还原为对象。

在序列化时,需要让对象实现Serializable接口。这个接口是一个标记接口,没有任何方法需要实现。当一个类实现了Serializable接口时,它的实例可以被序列化和反序列化。

  1. transient关键字的作用?/不想被序列化怎么办?

答:

transient关键字的作用是告诉Java虚拟机(JVM)不需要序列化该变量。当一个对象被序列化时,transient修饰的变量不会被序列化到输出流中。

如果不想被序列化,可以在类中定义一个名为serialVersionUID的静态常量,并为其分配一个唯一的值。这个值会在反序列化时用于验证序列化的类和当前类的一致性。如果没有定义serialVersionUID或者定义的值与当前类的不一致,就会抛出InvalidClassException异常。

  1. serialVersionUID版本号的作用?

答:

serialVersionUID是一个长整型数值,主要作用是作为序列化类的唯一标识,用于在序列化和反序列化过程中进行版本一致性校验。

在进行反序列化时,Java虚拟机(JVM)会把传来的字节流中的serialVersionUID与本地相应实体类的serialVersionUID进行比较,如果相同就认为是一致的,可以进行反序列化,否则就会出现序列化版本不一致的异常,即是InvalidCastException。

有两种指定serialVersionUID的方式:

一种是默认的1L,如 :private static final long serialVersionUID = 1L;

一种是根据类名、接口名、成员方法及属性等来生成一个64位的哈希字段。如果没有手动指定serialVersionUID,Java会根据类的结构自动生成一个版本号。这种生成规则是基于类的字段、方法和父类等信息进行计算,并使用哈希算法生成一个唯一标识。

  • 6
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值