Java Kryonet 发送对象时出错

标签 java class object illegalargumentexception kryonet

我正在使用 Kryonet 进行对象的 TCP 发送,特别是名为 TransferMessage 的对象:

public static class TransferMessage{String text; String username; Color color = Color.black;}

现在,我知道我必须调用kryo.register(TransferMessage.class)但是当我尝试连接到注册了所有类的服务器时,出现错误:

    Exception in thread "Server" com.esotericsoftware.kryo.KryoException: java.lang.IllegalArgumentException: Class is not registered: java.awt.Color
Note: To register this class use: kryo.register(java.awt.Color.class);
Serialization trace:
color (com.andrewlalisofficial.MessageTypes$TransferMessage)
    at com.esotericsoftware.kryo.serializers.FieldSerializer$ObjectField.write(FieldSerializer.java:585)
    at com.esotericsoftware.kryo.serializers.FieldSerializer.write(FieldSerializer.java:213)
    at com.esotericsoftware.kryo.Kryo.writeClassAndObject(Kryo.java:571)
    at com.esotericsoftware.kryonet.KryoSerialization.write(KryoSerialization.java:50)
    at com.esotericsoftware.kryonet.TcpConnection.send(TcpConnection.java:192)
    at com.esotericsoftware.kryonet.Connection.sendTCP(Connection.java:59)
    at com.esotericsoftware.kryonet.Server.sendToAllTCP(Server.java:435)
    at com.andrewlalisofficial.ChatServer.sendMessage(ChatServer.java:204)
    at com.andrewlalisofficial.ChatServer.checkCommand(ChatServer.java:124)
    at com.andrewlalisofficial.ChatServer$1.received(ChatServer.java:72)
    at com.esotericsoftware.kryonet.Server$1.received(Server.java:61)
    at com.esotericsoftware.kryonet.Connection.notifyReceived(Connection.java:246)
    at com.esotericsoftware.kryonet.Server.update(Server.java:208)
    at com.esotericsoftware.kryonet.Server.run(Server.java:356)
    at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.IllegalArgumentException: Class is not registered: java.awt.Color

我不明白,因为虽然我注册的类使用 Color 类,但我以前从未需要注册 String对象,所以我不明白这里有什么区别,我该如何修复这个错误?预先感谢您的帮助。

编辑:

这是一个最小的可重现代码,在序列化 Color 时显示错误:

// this works actually fine
public static void main(String[] args) {
    Kryo kryo = new Kryo();
    kryo.register(Color.class, new JavaSerializer());

    Color color = new Color(15006);

    Output output = new Output(new byte[1024]);
    kryo.writeObject(output, color);

    Input input = new Input(output.getBuffer());
    Color color2 = kryo.readObject(input, Color.class);

    if (!color.equals(color2)) throw new AssertionError();
}

最佳答案

默认情况下必须注册

String。我自己对这个错误感到有点惊讶,因为我总是能够序列化我没有注册的类,仅仅是因为 Kryo 拥有用于普通序列化类的默认序列化器。不管怎样,由于java.awt.Color实现了java.io.Serialized,我就这样做

kryoRegistrator.register(Color.class, new JavaSerializer());

如果你愿意,你也可以编写自己的序列化器(使用 Kryo),但我不确定它是否值得(它只是一个简单的序列化整数,标准库不可能效率低下)。如果你想要它,这里是:

public class ColorSerializer extends Serializer<Color> {
    @Override
    public Color read(Kryo kryo, Input input, Class<Color> clazz) {
        return new Color(input.readInt());
    }

    @Override
    public void write(Kryo kryo, Output output, Color color) {
        output.write(color.getRGB());
    }
}

关于Java Kryonet 发送对象时出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32877664/

相关文章:

java - 为什么 BufferedReader 的 2 个引用在这里不独立运行?

java - 在Java中创建泛型类型的实例?

Java:KeyListeners 确实有效,但仅在我键入空格时有效

ios - 迭代 Swift 扩展中的可用类?

java - 在java中创建类的实例时遇到问题

javascript - 当对象属性不存在时返回值

java - 我如何从无线和网络列表中删除 "Bluetooth "(Android Gingerbread)

java - 在与类和数据类型同名的方法中声明和初始化

javascript - $.数组的每个循环循环次数过多

javascript - 对年份数组进行排序(包括 BCE)