Java 日看一类(34)之IO包中的NotActiveException和NotSerializableException

本文详细介绍了NotActiveException和NotSerializableException两种序列化异常。NotActiveException在序列化或反序列化不活动时触发;NotSerializableException则在实例需被序列化但类未实现序列化接口时抛出。

NotActiveException异常类无引入包

继承自ObjectStreamException



类头注释如下:

* Thrown when serialization or deserialization is not active.

大意为:当序列化和反序列化不活动时抛出


该类含有如下的成员变量:

序列化ID

private static final long serialVersionUID = -3893467273049808895L;


该类含有如下的成员方法:

含有错误原因的构造方法

public NotActiveException(String reason) {
    super(reason);
}

默认构造方法:

public NotActiveException() {
    super();
}



该类实在没啥说的……简单易懂



NotSerializableException无引入包

继承自ObjectStreamException



类头注释如下:

/**
 * Thrown when an instance is required to have a Serializable interface.
 * The serialization runtime or the class of the instance can throw
 * this exception. The argument should be the name of the class.
 *
 * @author  unascribed
 * @since   JDK1.1
 */

大意如下:

当实例需要请求调用序列化接口抛出

序列化运行时或者该类被实例化时抛出该异常

参数是类名



该类含有如下成员变量:

序列化ID:

private static final long serialVersionUID = 2906642554793891381L;


该类含有如下成员方法:

构造函数(含错误原因

public NotSerializableException(String classname) {
    super(classname);
}

默认构造方法:

public NotSerializableException() {
    super();
}





该类往往是实例需被序列化而该类没有完成序列化接口时抛出,回去给类加个接口就行

类实现 `Serializable` 接口后仍出现 `java.io.NotSerializableException` 异常,可能有以下几种原因: ### 内部含非序列化的成员变量 如果一个类实现了 `Serializable` 接口,但该类中含了其他未实现 `Serializable` 接口的成员变量,在序列化该类的对象时,就会抛出 `java.io.NotSerializableException` 异常。例如在测试序列化 Android(使用 Eclipse)时,即便主类实现了 `Serializable`,若其内部有成员变量所属类未实现该接口,就会导致此异常 [^2]。 ### 父类未实现 Serializable 接口 当一个子类实现了 `Serializable` 接口,但它的父类没有实现该接口时,在序列化子类对象时,如果父类中有非 transient 修饰的实例变量,也可能会抛出该异常。因为序列化过程会尝试序列化父类的状态,而父类未实现 `Serializable` 接口就无法完成这一操作。 ### 序列化过程中的对象状态问题 在序列化过程中,如果对象的某些状态依赖于外部资源或运行时环境,这些状态可能无法被序列化。例如,对象持有一个打开的文件句柄、网络连接或数据库连接等,这些资源无法直接序列化,可能会引发异常。 ### 类定义发生变化 如果在序列化对象之后,类的定义发生了变化,比如添加、删除或修改了成员变量,在反序列化时可能会抛出 `java.io.NotSerializableException` 异常。这是因为序列化版本号(`serialVersionUID`)不一致,导致反序列化过程无法正确识别类的结构。 ### 代码逻辑问题 在某些情况下,可能是代码逻辑中错误地使用了未实现 `Serializable` 接口的对象。例如,在 Spark 中使用 `foreach` 函数处理 RDD 数据时,若对象需要反序列化,但其中含未实现 `Serializable` 接口的成员,就会出现异常 [^3]。 ### 示例代码说明问题 以下是一个简单的示例,展示了由于内部成员变量未实现 `Serializable` 接口而导致的异常: ```java import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectOutputStream; import java.io.Serializable; // 未实现 Serializable 接口的类 class NonSerializableClass { // 类的成员方法 } // 实现 Serializable 接口的类,但含非序列化成员变量 class MyClass implements Serializable { private NonSerializableClass nonSerializableField; public MyClass(NonSerializableClass nonSerializableField) { this.nonSerializableField = nonSerializableField; } } public class SerializationExample { public static void main(String[] args) { NonSerializableClass nonSerializableObj = new NonSerializableClass(); MyClass myObj = new MyClass(nonSerializableObj); try (FileOutputStream fos = new FileOutputStream("test.ser"); ObjectOutputStream oos = new ObjectOutputStream(fos)) { // 尝试序列化对象 oos.writeObject(myObj); } catch (IOException e) { e.printStackTrace(); // 这里会抛出 java.io.NotSerializableException 异常 } } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值