`
flowercat
  • 浏览: 361721 次
社区版块
存档分类
最新评论

内部类的序列化问题

阅读更多
   存储到memcached的所有对象都必须实现Serializable接口。今天修改系统缓存实现,从系统内部的Cache转到memcached。在转换过程中出现了内部类因为不能序列化导致设置缓存失败。写了以下的测试代码测试内部类的序列化:

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.Serializable;

import junit.framework.TestCase;

public class SerializableInnerClassTest extends TestCase
{

    class Person implements Serializable{
        String name;
        String password;
        public String getName()
        {
            return name;
        }
        public void setName(String name)
        {
            this.name = name;
        }
        public String getPassword()
        {
            return password;
        }
        public void setPassword(String password)
        {
            this.password = password;
        }
    }
    
    public void testSerializable(){
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        ObjectOutputStream oos;
        try
        {
            oos = new ObjectOutputStream(out);
            oos.writeObject(new Person());
            oos.close();
        }
        catch (IOException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        assertTrue(out.toByteArray().length > 0);   
    }
}

这个测试跑的话将会抛出java.io.NotSerializableException异常。
后查找资料,发现内部类改成静态内部类后,序列化成功。
这是咋会事情呢?静态内部类和非静态内部类在序列化过程中有什么不同呢?
分享到:
评论
5 楼 Morgan0916 2006-11-09  
You are welcome!
4 楼 flowercat 2006-11-09  
非静态内部类对外部类实例的引用可以使用SerializableInnerClassTest.this
3 楼 flowercat 2006-11-09  
谢谢楼上的,看来还是对内部类的理解不够!
2 楼 Morgan0916 2006-11-09  
我觉得这要从静态内部类和非静态内部类与外部类的关系上来考虑.

非静态内部类拥有对外部类的所有成员的完全访问权限,包括实例字段和方法。为实现这一行为,非静态内部类存储着对外部类的实例的一个隐式引用。序列化时要求所有的成员变量是Serializable,你现在SerializableInnerClassTest并没有implements Serializable,所以就抛出java.io.NotSerializableException异常!这样就是可以的!
public class SerializableInnerClassTest extends TestCase implements Serializable


非静态内部类和外部类没有那样的引用关系,自然也不会出那样的问题!
1 楼 karna 2006-11-09  
把Person定义为static

相关推荐

    序列化和反序列化的封装类

    这个过程同样依赖于特定的序列化类,例如BinaryFormatter或XmlSerializer。反序列化时,我们需要确保接收的数据与原始对象类型匹配,否则可能会抛出异常。 为了简化序列化和反序列化的操作,开发者通常会创建一个...

    java 序列化 将实体类本地序列化

    同时,如果你的类实现了`Serializable`,但其内部包含你不希望被序列化的成员,可以使用`transient`关键字标记这些字段,以跳过它们。 在小型网站数据存储的应用场景中,Java序列化可以作为简单的数据库替代方案,...

    redis使用过程中由于序列化工具引起的问题

    这篇博客讨论的就是这类问题,特别是如何理解和解决由序列化工具导致的困扰。 在Redis中,当我们存储复杂的数据结构,如Java对象时,需要将对象转换为可存储的格式,这就是序列化的过程。默认情况下,Redis并不提供...

    hessian学习基础篇——序列化和反序列化

    这对于优化自定义序列化逻辑或者解决Hessian使用中遇到的问题非常有帮助。 总结起来,Hessian是一种高效、轻量级的二进制序列化协议,特别适合于跨语言的网络通信。理解并掌握Hessian的基本概念和使用方法,能够...

    序列化类的作用Serializable

    需要注意的是,实现序列化的类应该谨慎处理其内部状态,因为序列化会保存对象的所有字段,包括私有(private)和受保护的(protected)成员。如果某个类的父类没有实现`Serializable`接口,那么子类仍然可以序列化,...

    四种反序列化与序列化

    - **BinaryFormatter序列化**:C#的 `System.Runtime.Serialization.Formatters.Binary.BinaryFormatter` 类提供了二进制序列化功能,它将对象转换为效率高的二进制表示,适合本地存储和高效数据传输。然而,由于...

    二进制序列化和XML序列化

    这种序列化形式通常用于内部存储或网络通信,因为它的数据紧凑且速度快。 1. **优点** - 存储效率高:二进制序列化的数据占用空间小,适合对内存和带宽有严格要求的场景。 - 快速:由于数据格式直接对应于机器...

    java序列化实现演示

    - 序列化可能会暴露对象的内部状态,因此对安全敏感的数据,谨慎使用序列化。 - 使用`transient`关键字标记不需要序列化的字段。 - `readObject()`和`writeObject()`方法可以自定义序列化和反序列化的逻辑。 总之,...

    java中的序列化与反序列化

    总的来说,Java的序列化和反序列化是Java开发中的重要概念,它们使得对象能够在不同环境之间进行传输和持久化,但也需要开发者关注其中的安全问题。理解和熟练掌握序列化机制,对于编写高效、安全的Java应用程序至关...

    Java中的序列化与反序列化.pdf

    虽然实现`Serializable`接口能够方便地进行序列化和反序列化,但需要注意的是,序列化会暴露对象的内部状态,可能引发安全问题。此外,如果一个类包含不希望被序列化的字段,可以通过添加`transient`关键字来标记...

    C#序列化学习的源码

    序列化可能导致安全问题,因为它可以暴露对象的内部状态。源码可能展示了如何保护敏感信息,比如使用加密或不序列化敏感字段。 10. **序列化在实际项目中的应用** 序列化在许多场景下都很有用,如持久化对象、...

    详细案例介绍json序列化与反序列化

    .NET Framework提供了多种序列化机制,其中`DataContractJsonSerializer`类可用于实现JSON序列化与反序列化。此类位于`System.Runtime.Serialization.Json`命名空间下,对于.NET Framework 3.5,需要添加对`System....

    C#序列化实例讲解,C#序列化实例源代码

    在C#中,可以使用`XmlSerializer`类实现XML序列化。例如: ```csharp using System.Xml.Serialization; public class Person { public string Name { get; set; } public int Age { get; set; } } Person ...

    Android 之 Parcelable 序列化

    在Android开发中,数据序列化是一个非常重要的概念,它允许对象的状态被保存和恢复,以便在不同的时间点或不同的环境中重建对象。Parcelable是Android平台提供的一种高效的数据序列化方式,比传统的Serializable接口...

    Protocol Buffer序列化对比Java序列化.

    【Protocol Buffer序列化对比Java序列化】 Protocol Buffer(简称PB)是Google开发的一种高效的数据序列化协议,而Java序列化是Java...而Java序列化则在简单的Java项目内部或已有大量Java序列化数据的情况下更为便利。

    python序列化反序列化和异常处理笔记.doc

    在进行序列化和反序列化操作时,需要注意的是不同库支持的类型和安全问题。例如,pickle库虽然方便,但可能导致安全风险,因为它可以序列化和恢复任何Python对象,包括可能含有恶意代码的对象。在处理不受信任的数据...

    java 序列化

    Java序列化还涉及到版本控制问题,即`serialVersionUID`。每个可序列化的类都有一个与此类相关的唯一标识符,用于版本控制。当类的结构发生改变时,如果未显式声明`serialVersionUID`,Java会自动生成,如果类结构...

    jackson库实现定制化的java序列化反序列化操作

    例如,如果我们有一个`Person`类,我们可能希望在序列化时不包含某些字段,或者在反序列化时忽略某些输入。通过使用`@JsonIgnore`注解,我们可以排除特定属性。另外,可以使用`@JsonCreator`注解来指定一个构造函数...

    Dictionary序列化源码 datatable序列化源码

    序列化`Dictionary`意味着将其内部存储的所有键值对转换为某种可持久化的格式,例如XML、JSON或二进制。这样可以保存程序状态并在后续运行时重新加载。 以下是一个简单的`Dictionary`序列化到XML的示例: ```...

    序列化数据序列化数据

    浅层序列化仅保存对象的可读写属性值,而不包括对象内部的数据。这通常用于XML序列化和Web服务。而深层序列化则更全面,不仅保存对象的所有可访问数据,还处理对象间的引用关系,确保整个对象图都被序列化。例如,...

Global site tag (gtag.js) - Google Analytics