• 陆离
    2019-06-08
    序列化会通过反射调用无参构造器返回一个新对象,破坏单例模式。
    解决方法是添加readResolve()方法,自定义返回对象策略。

    作者回复: 回答正确

     1
     44
  • 密码123456
    2019-06-08
    看到提问,才发现这竟然不是单例。回想内容是因为。可以把类路径上几乎所有实现了 Serializable 接口的对象都实例化。还真不知道怎么写?内部私有类实现,这种可以吗?

    作者回复: 线上代码发生错位了,已修正。

    导致这个问题的原因是序列化中的readObject会通过反射,调用没有参数的构造方法创建一个新的对象。

    所以我们可以在被序列化类中重写readResolve方法。

    private Object readResolve(){
            return singleInstance;
    }

     3
     5
  • waniz
    2019-07-05
    老师您好,Java序列化将数据转化为二进制字节流,json序列化将数据转化为json字符串。但是在物理层数据都是以电信号或模拟信号传输。那么从应用层到物理层数据的编码状态究竟是怎么变化的?出发点不同,最后都是二进制传输…忘解惑

    作者回复: Java序列化是将Java对象转化为二进制流,而Json序列化是将Json字符串转为二进制的过程,只是包装的数据格式不一样。

    
     4
  • kevin
    2019-06-09
    老师请教下,为什么spring cloud不使用protobuf, thrift等性能更高、支持跨平台的序列化工具,而且使用json?

    作者回复: springcloud是spring生态中的一部分,就目前spring生态很少引入非生态框架。但是我们可以自己实现springcloud兼容protobuf序列化。

    
     4
  • -W.LI-
    2019-06-08
    文中说Java序列化,不会序列化静态变量,这个单例的静态变量会被怎么处理啊?

    作者回复: 是的,Java序列化会调用构造函数,构造出一个新对象

    
     4
  • 疯狂咸鱼
    2019-09-14
    它会在反序列化过程中来验证序列化对象是否加载了反序列化的类,如果是具有相同类名的不同版本号的类,在反序列化中是无法获取对象的。老师,这句话能举个例子么,没太明白

    作者回复: 在Class类文件中默认会有一个serialNo作为序列化对象的版本号,无论在序列化方还是在反序列化方的class类文件中都存在一个默认序列号,在序列化时,会将该版本号加载进去,在反序列化时,会校验该版本号。

    
     3
  • 强哥
    2019-06-19
    首先为什么单例要实现Serializable接口呢?如果本身就不合理,那直接删掉Serializable即可,没必要为了本身的不合理,添加多余的方法,除非有特殊场景,否则这么这样的代码指定会被ugly
    
     2
  • 彦峰你要加油啊!
    2019-12-30
    稍微看了下评论,解决方法是在被序列化类中重写readResolve方法, 但是通过Jdk源码可以看出,虽然readResolve方法返回实例解决了单例模式被破坏的问题, 但实际上还是实例化了两次,只不过新创建的对象没有被返回而已.
    如果创建对象的动作发生频率加快,就意味着内存分配开销也会随之增大,应该使用注册式单例来解决这个问题.
    
     1
  • 天天向上
    2019-12-28
    想知道为什么用非Java的序列化方式的也需要实现Serializable接口?

    作者回复: 这是Java说明需要序列化的一种标识

    
    
  • 王圣军
    2019-12-26
    我们有时基于网络通讯的传输,有的不是直接使用实例序列化后传输,很多就是字符串转换为二进制流进行传输,这个应该是不涉及到序列化和反序列化的吧?

    作者回复: 这也是一个序列化过程,只不过是字符串对象转二进制的过程

    
    
  • td901105
    2019-12-05
    老师我想问一下如果使用非Java的序列化方式的话需要实现Serializable接口吗?

    作者回复: 需要的

    
    
  • yunfeng
    2019-10-14
    2019.10.14 打卡:选择序列化四个原则:编解码效率、所占空间、安全、是否支持多语言
    
    
  • 疯狂咸鱼
    2019-09-14
    那么java的NIO用到了java的序列化和反序列化么?有一样的问题么

    作者回复: NIO是一种通信模型,并没有包含序列化的内容,可以自己选择使用哪一种序列化

    
    
  • 疯狂咸鱼
    2019-09-14
    老师,所有在网络中传输信息都是要序列化么

    作者回复: 是的,不序列化与反序列化,则无法在内存中获取具体的信息用于业务逻辑中。

    
    
  • godtrue
    2019-09-07
    课后思考及问题
    1:老师能深入细致的讲讲JAVA怎么实现序列化的嘛?比如:一个对象怎么一步步神奇的变成一个字节数组的?对象中的属性、属性值、方法、以及此对象的信息怎么变成一个字节数组的?
    2:我们知道对象是通过在 ObjectInputStream 上调用 readObject() 方法进行反序列化的,这个方法其实是一个神奇的构造器,它可以将类路径上几乎所有实现了 Serializable 接口的对象都实例化。
    这个神奇的构造器的实现原理是啥?一个字节数组他怎么将其转换为一个对象的?很好奇,他知道字节数组多少位表示啥意思?然后一段一段的取,一段的翻译嘛?老师给讲讲呗?
    老师深入讲一下原理实现细节,API式的讲解不过瘾,和老师要深入理解的风格也不符呀😄
    展开

    作者回复: 序列化是将一个对象通过某种数据结构包装好对象中的具体属性和值,转换为二进制进行网络传输的一个过程。例如一个int类型的属性,数组是1000,转换为二进制则是4个字节的byte数组了。

    后面我会使用一个具体的例子来优化讲解这一讲。

    
    
  • Jerry
    2019-07-25
    老师,我试着写了一下这个问题的代码,但是发现Singleton 序列化和反序列化后会产生两个instance, 这个问题怎么解?以下是我的代码,
    '''
    ...
    public static void serializeMe() {
            try {
                ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("SingletonData.txt"));
                oos.writeObject(Singleton.getInstance());
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        public static Object deSerializeMe() {
            Object obj = null;
            try {
                ObjectInputStream ois = new ObjectInputStream(new FileInputStream("SingletonData.txt"));
                obj = ois.readObject();
            } catch (IOException | ClassNotFoundException e) {
                e.printStackTrace();
            }
            return obj;
        }

        private static class Singleton implements Serializable {
            int i;
            private static Singleton instance = null;
            private Singleton() {
                System.out.println("Executing constructor");
                i = 1;
            }

            // key change here !!!
            private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
                System.out.println("readObject before [i=" + i + "]");
                ois.defaultReadObject();
                instance = this; // After de-serialization, two objects of 'Singleton' class are created.
                System.out.println("readObject after [i=" + i + "]");
            }

            // thread unsafe here, don't care
            public static Singleton getInstance() {
                if (instance == null) {
                    instance = new Singleton();
                }
                System.out.println("An instance is returned");
                return instance;
            }

            // readResolve() is usually called after readObject()
            public Object readResolve() {
                System.out.println("Executing readResolve");
                return instance;
            }

            @Override
            public String toString() {
                return "Singleton [i=" + i + "]";
            }
        }
    '''
    展开
    
    
  • 辉
    2019-07-19
    hession是通过什么做序列化的?

    作者回复: hessian是用的hessian2序列化。

    
    
  • 17702158422
    2019-06-19
    可以定义一个静态属性 boolean flag = false, 在构造函数里 判断 flag是否为ture, 如果为true则抛出异常,否则将flag赋值为 true ,则可以在运行期防止反序列化时通过反射破坏单例模式
    
    
  • 草帽路飞
    2019-06-19
    老师,您好。Java 序列化的安全性中,序列化的时候执行按段循环对象链的代码为什么会导致 hashcode 成倍增长呀?
    
    
  • undifined
    2019-06-11
    老师 我们有一个需求,需要将一些更新前的数据保存起来用于回滚,保存的对象有一个 value 属性是 Object 类型的,赋值 BigDecimal 后使用 FastJson 序列化保存到数据库,回滚的时候再反序列化变成了Integer,考虑将 FastJson 改成 JDK 的序列化,但是又担心会造成性能问题,请问老师有什么建议吗

    作者回复: 请问改成JDK序列化的目的是什么?

    
    
我们在线,来聊聊吧