2016-04-05 15 views
0

私は将来実行できる関数のリストを作成したいと思います。関数のリストをシリアライズして復元する方法は?

まずリスト:

exec func1 
exec func2 
after loading: 
exec func1 
exec func2 

しかし、私はだけのシリアル化情報を使用して明確なロードを使用しようとしたとき、私はClassNotFoundException for ExampleF$1を得る:

import java.io.*; 
import java.util.ArrayList; 

class ExampleF implements Serializable{ 
    interface Executable extends Serializable{ void execute(); } 
    ArrayList<Executable> alFunc = new ArrayList<>(); 

    public static void main(String[] args) throws IOException, ClassNotFoundException { 
     ExampleF  ex1 =new ExampleF(); 
     Executable exec1 =new Executable() { 
      @Override 
      public void execute() { System.out.println("exec func1"); } 
     }; 
     Executable exec2 =new Executable() { 
      @Override 
      public void execute() { System.out.println("exec func2"); } 
     }; 

     ex1.alFunc.add(exec1); 
     ex1.alFunc.add(exec2); 
     ex1.alFunc.get(0).execute(); 
     ex1.alFunc.get(1).execute(); 

     ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("data1.dat")); 
     oos.writeObject(ex1); 
     oos.close(); 

     System.out.println("after loading:"); 
     ObjectInputStream ois = new ObjectInputStream(new FileInputStream("data1.dat")); 
     ExampleF ex2 = (ExampleF) ois.readObject(); 
     ois.close(); 
     ex2.alFunc.get(0).execute(); 
     ex2.alFunc.get(1).execute(); 
    } 
} 

がうまく働いた、出力がいた

import java.io.*; 
import java.util.ArrayList; 

class ExampleF implements Serializable{ 
    interface Executable extends Serializable{ void execute(); } 
    ArrayList<Executable> alFunc = new ArrayList<>(); 

    public static void main(String[] args) throws IOException, ClassNotFoundException { 
     ObjectInputStream ois = new ObjectInputStream(new FileInputStream("data1.dat")); 
     ExampleF ex2 = (ExampleF) ois.readObject(); 
     ois.close(); 
     ex2.alFunc.get(0).execute(); 
     ex2.alFunc.get(1).execute(); 
    } 
} 

どうすればこの問題を解決できますか?

  • 必要な機能の複数のリストを作成しますSerializeを
  • はのみのみ()を実行使用して必要なファイルをダウンロードした後、将来的にそれを使用してください。

おそらく関数のArrayListを格納する他の方法がありますか? P.P.私はJava7を使用します(必要な場合はJava8にアップグレートできます)。

答えて

2

exec1とexec2はメインメソッドのスコープ内で作成する匿名クラスなので、この問題が発生します。通常のクラス、静的なネストされたクラスに変換する必要があります。あるいは、以下のような静的変数として定義する必要があります。

public class ExampleF implements Serializable { 
    interface Executable extends Serializable { void execute(); } 
    ArrayList<Executable> alFunc = new ArrayList<>(); 
    private static Executable exec1 =new Executable() { 
     @Override 
     public void execute() { System.out.println("exec func1"); } 
    }; 
    private static Executable exec2 =new Executable() { 
     @Override 
     public void execute() { System.out.println("exec func2"); } 
    }; 
... 
+0

ありがとう、私はそれを試しました。しかし、この場合、2番目の例ではすべてのプライベートな静的内部クラスを記述できるはずです(逆シリアル化と関数実行コードのみ)。私はコンパクトなコード(関数の記述なし)を持っていたいと思います。シリアル化ファイルから関数のコードを取得したいと思います。または、私はローカルクラスの互換性のない例外を取得します:stream classdesc serialVersionUID = .... – Joysi

+0

@Joysiあなたがやりたいことははるかに複雑です。クラスコンテンツを直列化し、クラスをロードするために特定のクラスローダーに依存する必要があります。おそらく最も単純な方法は、RMIをそのまま使用することです。https://docs.oracle.com/javase/tutorial/rmi/ –

+0

標準的な方法はありません**直列化** Javaバイトコードの関数をさらに直列化する可能性あり.ArrayListの実行可能項目として。 – Joysi

1

このブログポストをご覧ください。匿名クラスを使用しています - http://programmeit.blogspot.in/2012/08/why-anonymous-classes-and-inner-classes.html

例#1と#2をよく見ると、#1にある匿名クラスは#2には存在しません。このような場合、JVMはそのクラスを見つけることができません。

+0

ありがとうございます。私は匿名の機能について知っています。私はそれを回避して一般的に決める方法を知らない。どのような説明もなく(クラスなどで)関数のリストを逆シリアル化する別の方法はありますか?シリアライズされたファイルのレディコードからダウンロードする。 – Joysi

+0

私はコードの2番目の部分を変更しないで維持したいと思います。 ObjectInputStream ois = new ObjectInputStream(new FileInputStream( "data1.dat"));ExampleF ex2 =(ExampleF)ois.readObject(); ois.close(); ex2.alFunc.get(0).execute(); ex2.alFunc.get(1).execute(); – Joysi

+0

それは問題です。匿名クラスのアイデンティティは、宣言されている親クラスと結びついています。これらのクラスをまだ利用できるようにしたい場合は、クラスパスのクラスを何とか取得する必要があります。選択クラスを他のクラスとは異なる場所からロードする独自のクラスローダーを作成している可能性があります。 –

関連する問題