在Java中序列化和反序列化接口

时间:2014-03-22 14:07:19

标签: java serialization deserialization

情景:

我有两个Java应用程序 - MasterSlaveMaster需要通过套接字发送到类DEParamSet的Slave实例。

DEParamSet:

    public class DEParamSet implements Serializable {

        private static final long serialVersionUID = 8151790178483218232L;
        public final float CR, F;
        public final int NP, D;
        public final Specimen specimen;
        public final IOptimizationFunction optFunction;

        // Constructor and some methods....
        ... some code ...
    }

IOptimizationFunction:

    public interface IOptimizationFunction extends Serializable {
        public double evaluate(Object[] values);
    }

Master创建此类的实例,对其进行序列化并通过套接字将其发送到Slave

代码片段:

    // Create objective function
    IOptimizationFunction opt = new IOptimizationFunction() {

        private static final long serialVersionUID = -5167105656008707046L;

        @Override
        public double evaluate(Object[] params) {
            return (double) params[0] * (double) params[1];
        }
    };
    // Create instance of DEParamSet with objective function defined above.
    ...some code to create it...
    // Start thread, which serializes the instance and sends it via socket.
    ...some code...

问题:

Master上,一切正常。没有例外。 Slave接收数据并尝试对其进行反序列化。抛出以下异常

  

抛出java.lang.ClassNotFoundException

DEParamSet类中没有错误,因为如果我使用optimization function = null创建它,那么Slave反序列化它没有问题。我尝试将实例序列化到Master中的文件中,然后将其反序列化。它有效。但是Slave无法反序列化实例,如果它实现了优化函数的实现。当然,slave包含IOptimizationFunction接口的定义。

请帮忙。

修改 我有班级TestingFunction。该课程如下:

    public abstract class TestingFunctions {
        public static double schwefel(Object[] params) {

            double res = 0d;
            for (int i = 0; i < params.length; i++) {
                res += (-1) * (double) params[i] * Math.sin(Math.sqrt(Math.abs((double) params[i])));
            }
            return res;
        }

        public static double rastrigin(Object[] params) {
            double res = 0d;
            for (int i = 0; i < params.length; i++) {
                res += Math.pow((double) params[i], 2) - 10 * Math.cos(2 * Math.PI * (Double) params[i]);
            }
            return res * 2 * params.length;
        }
    }

这些函数中的每一个都返回了类型double,参数为array of object。这等于double evaluate(Object[] params)接口中的方法IOptimizationFunction。所以,我的愿景是,master创建DEParamSet的对象,它将包含一些参数和接口IOptimizationFunction的具体实现。例如,可能的实现之一是:

    IOptimizationFunction opt = new IOptimizationFunction() {

        private static final long serialVersionUID = -5167105656008707046L;

        @Override
        public double evaluate(Object[] params) {
            return TestingFunctions.rastrigin(params);
        }
    };

在这种情况下,Rastrigin的功能被调用。但是将调用哪个函数,这会在运行时定义用户。他可以从TestingFunction类中的函数中进行选择。

1 个答案:

答案 0 :(得分:3)

IOptimizationFunction opt = new IOptimizationFunction() {

    private static final long serialVersionUID = -5167105656008707046L;

    @Override
    public double evaluate(Object[] params) {
        return (double) params[0] * (double) params[1];
    }
};

以上几行创建了一个匿名内部类的实例。然后,此实例被序列化并发送到从属。由于Slave在其类路径中没有此匿名内部类,因此无法对其进行反序列化。

确保将客户端和服务器共享的所有类放在一个公共项目中,并将此项目生成的jar文件放在两个应用程序(主服务器和从服务器)的类路径中。

相关问题