请教一个default的构造方法有关的问题

时间:2022-05-12 00:43:28
麻烦先看一下代码,注意Blip2的构造方法,将对象Blip2序列化之后,反序列化的时候会报异常,如果Blip2的构造方法是public的就没有问题,请问这个怎么解释呢?

import java.io.*;

class Blip2 implements Externalizable {

Blip2() {
System.out.println("Blip2 Constructor");
}

@Override
public void writeExternal(ObjectOutput out) throws IOException {
System.out.println("Blip2.writeExternal");
}

@Override
public void readExternal(ObjectInput in) throws IOException,
ClassNotFoundException {
System.out.println("Blip2.readExternal");
}

}

public class Blips {
public static void main(String[] args) throws FileNotFoundException, IOException, ClassNotFoundException {
System.out.println("Constructing objects:");
Blip2 b2 = new Blip2();

ObjectOutputStream o = new ObjectOutputStream(new FileOutputStream("Blips.out"));
System.out.println("Saving object:");
o.writeObject(b2);
o.close();

ObjectInputStream in = new ObjectInputStream(new FileInputStream("Blips.out"));
System.out.println("Recovering b2:");
b2 = (Blip2) in.readObject();

}
}


异常如下:Exception in thread "main" java.io.InvalidClassException:   no valid constructor

11 个解决方案

#1


你这个序列化一点意义都没有,序列化只保存非静态的成员,不保存任何静态成员和方法,而且反序列化的时候构造方法是不会被调用的,可能因为没成员在序列化过程中保存,才导致了构造方法的调用吧。所以如果不声明为public会报错

#2


引用 1 楼 u011562317 的回复:
你这个序列化一点意义都没有,序列化只保存非静态的成员,不保存任何静态成员和方法,而且反序列化的时候构造方法是不会被调用的,可能因为没成员在序列化过程中保存,才导致了构造方法的调用吧。所以如果不声明为public会报错
还是没理解你的意思

#3


引用 1 楼 u011562317 的回复:
你这个序列化一点意义都没有,序列化只保存非静态的成员,不保存任何静态成员和方法,而且反序列化的时候构造方法是不会被调用的,可能因为没成员在序列化过程中保存,才导致了构造方法的调用吧。所以如果不声明为public会报错
反序列化的时候不调用构造方法么?

#4


引用 3 楼 tayanxunhua 的回复:
Quote: 引用 1 楼 u011562317 的回复:

你这个序列化一点意义都没有,序列化只保存非静态的成员,不保存任何静态成员和方法,而且反序列化的时候构造方法是不会被调用的,可能因为没成员在序列化过程中保存,才导致了构造方法的调用吧。所以如果不声明为public会报错
反序列化的时候不调用构造方法么?
反序列化不会调用构造方法啊,只是根据保存的信息去还原一块类存区

#5


引用 4 楼 u011562317 的回复:
Quote: 引用 3 楼 tayanxunhua 的回复:

Quote: 引用 1 楼 u011562317 的回复:

你这个序列化一点意义都没有,序列化只保存非静态的成员,不保存任何静态成员和方法,而且反序列化的时候构造方法是不会被调用的,可能因为没成员在序列化过程中保存,才导致了构造方法的调用吧。所以如果不声明为public会报错
反序列化的时候不调用构造方法么?
反序列化不会调用构造方法啊,只是根据保存的信息去还原一块类存区

那我如果把构造函数改成public的,那么怎么会执行那段儿代码呢?

#6


反序列化的时候先解析序列号出来的文件,解析出classname,根据classname来构造Blip2这个对象,构造的时候使用的是class.newInstance(),使用的时public的构造函数,你的时default的所以报错说no valid constructor

#7


引用 6 楼 abstruct 的回复:
反序列化的时候先解析序列号出来的文件,解析出classname,根据classname来构造Blip2这个对象,构造的时候使用的是class.newInstance(),使用的时public的构造函数,你的时default的所以报错说no valid constructor
class.newInstance()会导致默认构造函数的调用,如果没有默认构造函数,编译器会提供一个默认构造函数,你试试不要不带参数的构造函数,会不会导致错误,如果不会导致错误,就该是这样的了

#8


引用 6 楼 abstruct 的回复:
反序列化的时候先解析序列号出来的文件,解析出classname,根据classname来构造Blip2这个对象,构造的时候使用的是class.newInstance(),使用的时public的构造函数,你的时default的所以报错说no valid constructor
 可是如果我使用default修饰构造方法,为什么无法找到呢?肯定是因为访问权限的问题了,那么在哪里执行的Class.newInstance()呢?(我看了下源码,不知道在哪里执行的你所说的Class.newInstance())

#9


引用 7 楼 u011562317 的回复:
Quote: 引用 6 楼 abstruct 的回复:

反序列化的时候先解析序列号出来的文件,解析出classname,根据classname来构造Blip2这个对象,构造的时候使用的是class.newInstance(),使用的时public的构造函数,你的时default的所以报错说no valid constructor
class.newInstance()会导致默认构造函数的调用,如果没有默认构造函数,编译器会提供一个默认构造函数,你试试不要不带参数的构造函数,会不会导致错误,如果不会导致错误,就该是这样的了
不是这样的,如果没有默认的构造函数,同样也会报错

#10


因为你的class就不是public的而是default的,所以构造函数默认就是default的,所以你需要手动审批构造函数是public,你可以把Blip2改为public class试试 请教一个default的构造方法有关的问题

#11


当然可能调用的不是newInstance的方法,但是肯定调用的时无参构造函数,而且是public的

#1


你这个序列化一点意义都没有,序列化只保存非静态的成员,不保存任何静态成员和方法,而且反序列化的时候构造方法是不会被调用的,可能因为没成员在序列化过程中保存,才导致了构造方法的调用吧。所以如果不声明为public会报错

#2


引用 1 楼 u011562317 的回复:
你这个序列化一点意义都没有,序列化只保存非静态的成员,不保存任何静态成员和方法,而且反序列化的时候构造方法是不会被调用的,可能因为没成员在序列化过程中保存,才导致了构造方法的调用吧。所以如果不声明为public会报错
还是没理解你的意思

#3


引用 1 楼 u011562317 的回复:
你这个序列化一点意义都没有,序列化只保存非静态的成员,不保存任何静态成员和方法,而且反序列化的时候构造方法是不会被调用的,可能因为没成员在序列化过程中保存,才导致了构造方法的调用吧。所以如果不声明为public会报错
反序列化的时候不调用构造方法么?

#4


引用 3 楼 tayanxunhua 的回复:
Quote: 引用 1 楼 u011562317 的回复:

你这个序列化一点意义都没有,序列化只保存非静态的成员,不保存任何静态成员和方法,而且反序列化的时候构造方法是不会被调用的,可能因为没成员在序列化过程中保存,才导致了构造方法的调用吧。所以如果不声明为public会报错
反序列化的时候不调用构造方法么?
反序列化不会调用构造方法啊,只是根据保存的信息去还原一块类存区

#5


引用 4 楼 u011562317 的回复:
Quote: 引用 3 楼 tayanxunhua 的回复:

Quote: 引用 1 楼 u011562317 的回复:

你这个序列化一点意义都没有,序列化只保存非静态的成员,不保存任何静态成员和方法,而且反序列化的时候构造方法是不会被调用的,可能因为没成员在序列化过程中保存,才导致了构造方法的调用吧。所以如果不声明为public会报错
反序列化的时候不调用构造方法么?
反序列化不会调用构造方法啊,只是根据保存的信息去还原一块类存区

那我如果把构造函数改成public的,那么怎么会执行那段儿代码呢?

#6


反序列化的时候先解析序列号出来的文件,解析出classname,根据classname来构造Blip2这个对象,构造的时候使用的是class.newInstance(),使用的时public的构造函数,你的时default的所以报错说no valid constructor

#7


引用 6 楼 abstruct 的回复:
反序列化的时候先解析序列号出来的文件,解析出classname,根据classname来构造Blip2这个对象,构造的时候使用的是class.newInstance(),使用的时public的构造函数,你的时default的所以报错说no valid constructor
class.newInstance()会导致默认构造函数的调用,如果没有默认构造函数,编译器会提供一个默认构造函数,你试试不要不带参数的构造函数,会不会导致错误,如果不会导致错误,就该是这样的了

#8


引用 6 楼 abstruct 的回复:
反序列化的时候先解析序列号出来的文件,解析出classname,根据classname来构造Blip2这个对象,构造的时候使用的是class.newInstance(),使用的时public的构造函数,你的时default的所以报错说no valid constructor
 可是如果我使用default修饰构造方法,为什么无法找到呢?肯定是因为访问权限的问题了,那么在哪里执行的Class.newInstance()呢?(我看了下源码,不知道在哪里执行的你所说的Class.newInstance())

#9


引用 7 楼 u011562317 的回复:
Quote: 引用 6 楼 abstruct 的回复:

反序列化的时候先解析序列号出来的文件,解析出classname,根据classname来构造Blip2这个对象,构造的时候使用的是class.newInstance(),使用的时public的构造函数,你的时default的所以报错说no valid constructor
class.newInstance()会导致默认构造函数的调用,如果没有默认构造函数,编译器会提供一个默认构造函数,你试试不要不带参数的构造函数,会不会导致错误,如果不会导致错误,就该是这样的了
不是这样的,如果没有默认的构造函数,同样也会报错

#10


因为你的class就不是public的而是default的,所以构造函数默认就是default的,所以你需要手动审批构造函数是public,你可以把Blip2改为public class试试 请教一个default的构造方法有关的问题

#11


当然可能调用的不是newInstance的方法,但是肯定调用的时无参构造函数,而且是public的