Java NotSerializableException с пользовательским пакетом данных
Сейчас я работаю над простой структурой сервер-клиент для будущих проектов. Я решил, что будет лучше создать свой собственный пакет данных с пользовательской информацией заголовка, такой как локальный / публичный ip, отметка времени и т. Д. Ниже приведен класс, который я придумал:
public class DataPackage {
private Object object;
private Date time;
private long timeMs;
private boolean responded;
private String publicIp;
private String internalIp;
private int hash;
public DataPackage(Object object) {
this.object = object;
this.responded = false;
this.time = Calendar.getInstance().getTime();
this.timeMs = System.currentTimeMillis();
this.publicIp = this.generatePublicIp();
this.internalIp = this.generateInternalIp();
this.hash = System.identityHashCode(this);
}
private String generatePublicIp() {
try {
URL whatismyip = new URL("http://checkip.amazonaws.com");
BufferedReader in = new BufferedReader(new InputStreamReader(whatismyip.openStream()));
return in.readLine();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
private String generateInternalIp() {
try {
return InetAddress.getLocalHost().getHostAddress();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}
(Я удалил геттеры и сеттеры)
Я решил использовать объект, чтобы я мог отправить что-нибудь в классе. Он хорошо компилируется, но если я пытаюсь отправить простую строку, упакованную в классе, я получаю NotSerializableException. Существуют ли какие-либо атрибуты или поля, которые нельзя преобразовать в поток, или я должен изменить класс на общий? Я НЕ эксперт в области потоков и сетей, поэтому я благодарен за каждую помощь и объяснения, которые я могу получить.
ПРИМЕЧАНИЕ. Я не являюсь носителем английского языка, поэтому прошу прощения за любые орфографические / грамматические проблемы.
3 ответа
Вы должны реализовать интерфейс Serializable, чтобы класс передавался по сети.
Измените первую строку вашего класса на:
import java.io.Serializable;
public class DataPackage implements Serializable{
Ваш класс должен реализовывать интерфейс Serializable.
Также обратите внимание, что каждое свойство вашего класса, в вашем случае объект должен также реализовать этот интерфейс для правильной работы сериализации.
Поэтому я хотел бы сделать этот класс универсальным, чтобы заставить объект реализовать интерфейс Serializable.
РЕДАКТИРОВАТЬ: например, если вы попытаетесь сериализовать DataPackage, который содержит ByteBuffer(который не Serializable), как это: new DataPackage(ByteBuffer.allocate(1))
, вы получите исключение.
попробуй это:
import java.io.Serializable;
public class DataPackage<T extends Serializable> implements Serializable{
private T object;
private Date time;
private long timeMs;
private boolean responded;
private String publicIp;
private String internalIp;
private int hash;
public DataPackage(T object) {
this.object = object;
this.responded = false;
this.time = Calendar.getInstance().getTime();
this.timeMs = System.currentTimeMillis();
this.publicIp = this.generatePublicIp();
this.internalIp = this.generateInternalIp();
this.hash = System.identityHashCode(this);
}
private String generatePublicIp() {
try {
URL whatismyip = new URL("http://checkip.amazonaws.com");
BufferedReader in = new BufferedReader(new InputStreamReader(whatismyip.openStream()));
return in.readLine();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
private String generateInternalIp() {
try {
return InetAddress.getLocalHost().getHostAddress();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}
Таким образом, вы можете быть уверены, что все объекты, которые вы пытаетесь отправить, являются сериализуемыми.
Если вы не хотите использовать дженерики, сделайте объект типа Serializable следующим образом:
import java.io.Serializable;
public class DataPackage implements Serializable{
private Serializable object;
private Date time;
private long timeMs;
private boolean responded;
private String publicIp;
private String internalIp;
private int hash;
public DataPackage(Serializable object) {
this.object = object;
this.responded = false;
this.time = Calendar.getInstance().getTime();
this.timeMs = System.currentTimeMillis();
this.publicIp = this.generatePublicIp();
this.internalIp = this.generateInternalIp();
this.hash = System.identityHashCode(this);
}
private String generatePublicIp() {
try {
URL whatismyip = new URL("http://checkip.amazonaws.com");
BufferedReader in = new BufferedReader(new InputStreamReader(whatismyip.openStream()));
return in.readLine();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
private String generateInternalIp() {
try {
return InetAddress.getLocalHost().getHostAddress();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}
java.io.NotSerializableException
бросается, когда ваш объект не сериализуем, что означает, что ваш object
или любой non-transient
свойство этого объекта не реализует Serializable
интерфейс. И в вашем случае, DataPackage
не Сериализуем. Serializable
это маркер interface
который в основном говорит JVM
что нибудь instance
из Serializable
Тип может быть сериализован. Здесь вы можете просмотреть документы Serializable и NotSerializableException.