Java 文章中可外化的区别
我在一篇文章中讨论了序列化和可外化的概念,我发现。。。“外部化接口不能由Java中的内部类实现,因为Java中内部类的所有构造函数都将始终接受封闭类的实例作为前置参数,因此内部类不能有无参数构造函数。内部类只能通过实现可序列化接口来实现对象序列化。“Java 文章中可外化的区别,java,serialization,Java,Serialization,我在一篇文章中讨论了序列化和可外化的概念,我发现。。。“外部化接口不能由Java中的内部类实现,因为Java中内部类的所有构造函数都将始终接受封闭类的实例作为前置参数,因此内部类不能有无参数构造函数。内部类只能通过实现可序列化接口来实现对象序列化。“ 请告知上面几行的含义。内部类构造函数有一个隐式的第一个参数-对其封闭类的引用,它是不可见的,是由javac添加的。如果您反编译内部类字节码,您可以看到它。因此,外部化所需的内部类中不可能有任何参数构造函数。这将没有编译错误。您甚至可以使用write
请告知上面几行的含义。内部类构造函数有一个隐式的第一个参数-对其封闭类的引用,它是不可见的,是由javac添加的。如果您反编译内部类字节码,您可以看到它。因此,外部化所需的内部类中不可能有任何参数构造函数。这将没有编译错误。您甚至可以使用writeObject编写可外部化的内部类的实例。但是,只要您尝试使用readObject读取它,您就会得到如下结果
java.io.InvalidClassException: Test1$Test2; no valid constructor
实现Externalizable接口的类的规则之一是: “类必须有一个公共的无参数构造函数” 创建包含内部类的类并对其进行编译时,
javac
会为内部类创建一个参数化构造函数,该构造函数包含对内部类的.class
文件中封闭类的引用,而不管您是否在内部类中创建了无参数构造函数n按照下面给出的代码:
import java.io.*;
class ExternalizationDemo
{
public ExternalizationDemo(){System.out.println("Calling external");}
class MyClass implements Externalizable
{
int i = 90;
public MyClass()
{
System.out.println("MyClass Constructor");
i = 299;
}
public void writeExternal(ObjectOutput out)throws IOException
{
System.out.println("Write external of MyClass");
}
public void readExternal(ObjectInput in)throws IOException,ClassNotFoundException
{
System.out.println("Read external of MyClass");
}
}
public static void main(String[] args) throws Exception
{
ExternalizationDemo demo = new ExternalizationDemo();
ExternalizationDemo.MyClass mc = demo.new MyClass();
ObjectOutputStream ous = new ObjectOutputStream(new FileOutputStream("Inner.ser"));
ous.writeObject(mc);
ous.close();
System.out.println("Write successfull");
ObjectInputStream oins = new ObjectInputStream(new FileInputStream("Inner.ser"));
mc = (ExternalizationDemo.MyClass)oins.readObject();//throws java.io.InvalidClassException at this line
System.out.println("Read the object successfully");
}
}
对于上面的代码javac
createExternalizationDemo$MyClass.class
来表示内部类.class
文件。使用javap
反汇编代码时,我们得到以下指令集:
Compiled from "ExternalizationDemo.java"
class ExternalizationDemo$MyClass extends java.lang.Object implements java.io.Ex
ternalizable{
int i;
final ExternalizationDemo this$0;
public ExternalizationDemo$MyClass(ExternalizationDemo);
Code:
0: aload_0
1: aload_1
2: putfield #1; //Field this$0:LExternalizationDemo;
5: aload_0
6: invokespecial #2; //Method java/lang/Object."<init>":()V
9: aload_0
10: bipush 90
12: putfield #3; //Field i:I
15: getstatic #4; //Field java/lang/System.out:Ljava/io/PrintStream;
18: ldc #5; //String MyClass Constructor
20: invokevirtual #6; //Method java/io/PrintStream.println:(Ljava/lang/Str
ing;)V
23: aload_0
24: sipush 299
27: putfield #3; //Field i:I
30: return
public void writeExternal(java.io.ObjectOutput) throws java.io.IOException;
Code:
0: getstatic #4; //Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc #7; //String Write external of MyClass
5: invokevirtual #6; //Method java/io/PrintStream.println:(Ljava/lang/Str
ing;)V
8: return
public void readExternal(java.io.ObjectInput) throws java.io.IOException, java
.lang.ClassNotFoundException;
Code:
0: getstatic #4; //Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc #8; //String Read external of MyClass
5: invokevirtual #6; //Method java/io/PrintStream.println:(Ljava/lang/Str
ing;)V
8: return
}
我希望这能澄清为什么内部类不能实现
Externalizable
接口。你知道内部类吗?文章内容完全错误。我能够在内部类中实现Externalizable,并且没有任何编译错误,而且我还定义了一个无参数构造函数。@panky1986你能发布upda吗te代码,以便我能够掌握..!检查这里,假设此限制仅适用于非静态内部类。
Exception in thread "main" java.io.InvalidClassException: ExternalizationDemo$MyClass; ExternalizationDemo$MyClass; no valid constructor