慕粉704747
反序列化出来的是一个对象,对象就好比new Student();创建出来的实例化对象它是在堆内存里的;
而把实例化的对象赋值给变量也就是 Object p = new Student(); 这个变量p只是个变量,他在栈内存里,存储的是右边堆内存里对象的引用地址。
而输出这个变量P的话实际上也是输出他存储的引用地址
qq_邪炎_0
这个序列化意思是,当你序列化一个文件并且写入的时候,在你写入的数据文件中是有实现了序列化接口的那些类的信息。这样你反序列化,他们都存在就不会重新创建了。
但是如果你父类没有序列化,子类序列化了,当你序列化写的时候,父类是没有被写入的,当你反序列化读取的时候,你读取到了子类,但是没有发现父类,此时就会去调用父类的构造方法了,此时就有输出了
gspsfaf
打错了data换成date
yyz要学java
问题原因:
//由于你的代码多了下面这一行 Bar2 bar2 = new Bar2(); //新建一个Bar2对象。调用new方法时,程序会自动调用Bar2的构造方法 //你控制台多出那一行bar2,就是这个Bar2的构造方法输出的
解决方法:
//注释掉或者直接删除下面这行代码可以得到和老师同样的结果 //Bar2 bar2 = new Bar2(); //该程序是为了测试反序列化得到对象是否调用其构造方法 //因此重新新建一个Bar2的实体对象是完全没有必要的,反而会混淆测试结果
qq_Divergent_2
我这里用你的没有一点问题诶 是不是main函数有问题
你把序列、反序列封装成函数,那我的main函数是这样的:
ObjectOutputStream oos = new ObjectOutputStream(
new FileOutputStream("demo/obj2.dat")
);
Bar2 bar2 = new Bar2();
oos.writeObject(bar2);
oos.flush();
oos.close();
// ObjectInputStream ois = new ObjectInputStream(
// new FileInputStream("demo/obj2.dat")
// );
// Bar2 bar2 = (Bar2)ois.readObject();
// System.out.println(bar2);
// ois.close();
初级阶段
你将FOO类定义到了ObjeectSer2里面了,成为了内部类,放在类外面再试试
醉里挑灯开车
只要把老师的操作,换汤不换药(连汤也不换也行),自己再跟着打一遍,每节课都打的话,就很厉害了。
现在只是零碎的知识点,这样练就行,以后的项目,才能真的锻炼技能。
慕粉4175237
数组开拓了内存空间,但是实际存放数据的可能只有部分,所以只需要序列化存放数据的那一部分
爱笑的她
老师讲解时,都是实例化子类对象的,因为子类对象已经实例化过的,所以不会报错,如果此时直接对没有序列化的父类对象进行对象的文件存储与读取操作、网络传输时均会报错的。
qq_noheartnoswe_04385033
你可以先判断文件是否存在file.exists(),要是不存在就进行创建file.createNewFile();这样操作就没问题了
雪中_悍刀行
这个不是内部类,定义在类中或方法中的类才叫内部类
Java中允许在一个.java文件中创建多个类,但只能有个一个类修饰符是public
Coder编程
在父类没有实现 Serializable 接口时,虚拟机是不会序列化父对象的,也就是说序列化后的流中没有父类的信息;而一个 Java 对象的构造必须先有父对象,才有子对象,反序列化也不例外。所以反序列化时,为了构造父对象,只能调用父类的无参构造函数作为默认的父对象。
慕粉3170877
1、定义类 Foo、Foo1、Foo2 、 Bar、 Bar1、Bar2时要定义在类ObjectSeriaDemo的花括号外面
2、要运行起来的话,要在当前项目下新建个文件夹,文件夹的名字为demo
package com.imooc;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
public class ObjectSeriaDemo {
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
/*
* ObjectOutputStream oos=new ObjectOutputStream( new
* FileOutputStream("demo/obj1.dat")); Foo2 foo2=new Foo2();
* oos.writeObject(foo2); oos.flush(); oos.close(); /* ObjectInputStream
* ois=new ObjectInputStream( new FileInputStream("demo/obj1.dat"));
* Foo2 foo2=(Foo2)ois.readObject(); System.out.println(foo2);
* ois.close();
*/
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(
"demo/obj1.dat"));
Bar2 bar2 = new Bar2();
oos.writeObject(bar2);
oos.flush();
oos.close();
/*
* ObjectInputStream ois=new ObjectInputStream( new
* FileInputStream("demo/obj1.dat")); Bar2 bar2=(Bar2)ois.readObject();
* System.out.println(bar2); ois.close();
*/
}
class Foo implements Serializable {
public Foo() {
System.out.println("foo");
}
}
class Foo1 extends Foo {
public Foo1() {
System.out.println("foo1");
}
}
class Foo2 extends Foo1 {
public Foo2() {
System.out.println("foo2");
}
}
class Bar {
public Bar() {
System.out.println("bar");
}
}
class Bar1 extends Bar implements Serializable {
public Bar1() {
System.out.println("bar1");
}
}
class Bar2 extends Bar1 {
public Bar2() {
System.out.println("bar2");
}
}
}
精慕门7137578
说子类和父类,继承序列化接口是,它的构造函数,会怎样显示和调用。当父类实现了序列化接口时,子类被调用,其父类的构造函数是不会被显示和调用的,当父类没有实现序列化接口,而是其子类继承了序列化接口,其父类的构造函数会被显示和调用。
SheldonParsons
所以其实父类需不需要序列化接口是要根据实际情况判断的,看你的父类对象需不需要被传输。
这一节是想告诉我们在你的父类实现或者没有实现序列化接口后,在反序列化时会发生的情况。
所以~知道这个和性能没有太大关系,还是要看实际情况啦
bigfire
我说一下我的理解吧:说之前首先要说一下概念,序列化就是将对象转换为字节序列,通俗点就是讲创建出来的对象状态保存起来(构造函数初始化之后的)
父类如果没有实现序列接口,而子类实现序列接口,那么父类对象就不会被序列化,也就不会被保存,而子类却可以被序列化,即保存
Java中构造一个对象,首先得先构造父类对象,才会构造子类对象,所以在反序列化子类时,就会调用父类构造方法来作为默认的父类对象,而子类因为已经被序列化了(已经调用过子类构造方法的状态),所以就不会再调用子类自己的构造方法
qq_若兮如初_0
楼主可不可以把错误的原因一起放上来呢?Bar2方法有没有写?
慕容8281072
序列化和反序列化可以同时操作,比如读取文件1里的内容后,再把该文件1的内容拷贝(写入)到文件2里去,这样就需要同时操作输入和输出,输出表示序列化,输入表示反序列化。老师为运行程序方便才每次运行都要把另一个操作注释掉,不然可能运行出现某些错误。
差不多先生1234
因为 你是 Bar2 bar2 = new Bar2(); bar2 = (Bar2)ois.readObject();
但是老师写的是 Bar2 bar2 = (Bar2)ois.readObject(); 这里要注意的是 老师并没有去new一个Bar2对象
而你却是先new出来的 肯定会调用父类的构造函数
收拾好鑫情
因为序列化写入那么文件,父类可以被序列化,父类也被写进去了!直接在那个文件里就能找到父类,所以不需要调用父类的构造函数。反之一样!
学霸学吧
Foo2不在ObjectSeriaDemo2中,在外面哦
ziom
类型强制转换时,就会调用构造函数
吴登广
foo2类中没进行toString 操作,默认调用foo2对象的内存地址
阿丁4513
子类的构造方法中,第一句有一个隐式的 super(); 调用父类的构造方法,然后再执行子类构造方法的方法体。bar2的构造方法中输出“bar2”之前调用其父类bar1的构造方法,bar1的构造方法中在输出“bar1”之前调用其父类bar的构造方法,输出 bar ,然后执行bar1的方法体输出bar1,之后再执行bar2的方法体输出bar2,结果就是 bar bar1 bar2
doppler
用来在网络传输中进行对象的传输
小破_孩
lynhao
EpisodeOne
泥尘
方法签名由方法名称和一个参数列表(方法的参数的顺序和类型)组成。
helson