Java 文章中可外化的区别

Java 文章中可外化的区别,java,serialization,Java,Serialization,我在一篇文章中讨论了序列化和可外化的概念,我发现。。。“外部化接口不能由Java中的内部类实现,因为Java中内部类的所有构造函数都将始终接受封闭类的实例作为前置参数,因此内部类不能有无参数构造函数。内部类只能通过实现可序列化接口来实现对象序列化。“ 请告知上面几行的含义。内部类构造函数有一个隐式的第一个参数-对其封闭类的引用,它是不可见的,是由javac添加的。如果您反编译内部类字节码,您可以看到它。因此,外部化所需的内部类中不可能有任何参数构造函数。这将没有编译错误。您甚至可以使用write

我在一篇文章中讨论了序列化和可外化的概念,我发现。。。“外部化接口不能由Java中的内部类实现,因为Java中内部类的所有构造函数都将始终接受封闭类的实例作为前置参数,因此内部类不能有无参数构造函数。内部类只能通过实现可序列化接口来实现对象序列化。


请告知上面几行的含义。

内部类构造函数有一个隐式的第一个参数-对其封闭类的引用,它是不可见的,是由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
create
ExternalizationDemo$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