Che cosa vuol dire: la classe serializzabile non dichiara un campo serialVersionUID finale statica? [duplicare]
-
21-09-2019 - |
Domanda
Questa domanda ha già una risposta qui:
Ho il messaggio di avvertimento dato nel titolo. Vorrei capire e rimuoverlo. Ho trovato già alcune risposte su questo argomento, ma non capisco queste risposte a causa di un sovraccarico di termini tecnici. E 'possibile spiegare la questione con parole semplici?
P.S. So quello che OOP è. So quello che è oggetto, classe, metodo, di campo e di istanze.
P.P.S. Se qualcuno ha bisogno del mio codice è qui:
import java.awt.*;
import javax.swing.*;
public class HelloWorldSwing extends JFrame {
JTextArea m_resultArea = new JTextArea(6, 30);
//====================================================== constructor
public HelloWorldSwing() {
//... Set initial text, scrolling, and border.
m_resultArea.setText("Enter more text to see scrollbars");
JScrollPane scrollingArea = new JScrollPane(m_resultArea);
scrollingArea.setBorder(BorderFactory.createEmptyBorder(10,5,10,5));
// Get the content pane, set layout, add to center
Container content = this.getContentPane();
content.setLayout(new BorderLayout());
content.add(scrollingArea, BorderLayout.CENTER);
this.pack();
}
public static void createAndViewJFrame() {
JFrame win = new HelloWorldSwing();
win.setTitle("TextAreaDemo");
win.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
win.setVisible(true);
}
//============================================================= main
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable(){
public void run(){
createAndViewJFrame();
}
});
}
}
Soluzione
javadoc :
Gli associati serializzazione runtime con ciascuna classe serializzabile un numero di versione, chiamato
serialVersionUID
, che viene utilizzato durante deserializzazione per verificare che il mittente e il destinatario di un oggetto serializzato sono caricati classi per l'oggetto che sono compatibili per quanto riguarda serializzazione. Se il ricevitore ha caricato un classe per l'oggetto che ha unserialVersionUID
diversa da quella della classe del mittente corrispondente, quindi deserializzazione si tradurrà in unInvalidClassException
. Una classe serializzabile può dichiarare la propriaserialVersionUID
esplicitamente dichiarando un campo denominato"serialVersionUID"
che deve essere statica, definitiva, e di tipo lungo:
È possibile configurare il vostro IDE a:
- ignorare questo, invece di dare un avvertimento.
- autogenerate un id
Come per la tua domanda aggiuntiva "Può essere che il messaggio di avviso discusso è un motivo per cui la mia applicazione GUI congelare?":
No, non può essere. Esso può causare un problema solo se si serializzazione di oggetti e deserializzazione in un posto diverso (o tempo), dove (quando) la classe è cambiato, e non determinerà il congelamento, ma in InvalidClassException
.
Altri suggerimenti
I motivi di allarme sono documentate qui , e le semplici correzioni sono per disattivare l'avviso o mettere la seguente dichiarazione nel codice di fornire l'UID versione. Il valore attuale non è rilevante, iniziare con 999, se volete, ma cambiarla quando si apportano modifiche incompatibili alla classe è.
public class HelloWorldSwing extends JFrame {
JTextArea m_resultArea = new JTextArea(6, 30);
private static final long serialVersionUID = 1L;
Le altre risposte finora hanno un sacco di informazioni tecniche. Cercherò di rispondere, come richiesto, in termini semplici.
La serializzazione è ciò che si fa a un'istanza di un oggetto, se si desidera eseguire il dump ad un buffer grezzo, salvarlo su disco, trasportarlo in un flusso binario (ad esempio, l'invio di un oggetto su un socket di rete), o in altro modo creare una rappresentazione binaria serializzata di un oggetto. (Per maggiori informazioni sulla serializzazione vedere Java serializzazione su Wikipedia ).
Se non avete intenzione di serializzare la classe, è possibile aggiungere l'annotazione appena sopra la vostra classe @SuppressWarnings("serial")
.
Se avete intenzione di serializzare, allora avete una miriade di cose di cui preoccuparsi tutto incentrato sul corretto utilizzo dei UUID. In sostanza, l'UUID è un modo per "versione" di un oggetto che si sarebbe serializzare in modo che qualunque processo è di de-serializzazione sa che di de-serializzazione correttamente. Vorrei guardare Garantire un adeguato controllo di versione per oggetti serializzati per ulteriori informazioni.
deve essere cambiato ogni volta qualcosa di cambiamenti che colpisce la serializzazione (campi aggiuntivi, campi rimosso, cambiamento di ordine dei campi, ...)
Non è corretto, e sarete in grado di citare una fonte authoriitative per tale affermazione. Esso dovrebbe essere cambiato ogni volta che si apporta una modifica che non è compatibile con le regole date nel versioni di oggetti Serializable sezione della serializzazione degli oggetti Specification , che fa specificamente non includono campi o cambiamento di ordine dei campi aggiuntivi, e quando non hai fornito readObject(), writeObject(),
e / o readResolve()
o /writeReplace()
metodi e / o una dichiarazione serializableFields
che potrebbe far fronte al cambiamento.
Ogni classe che può essere serializzato (vale a dire attrezzi Serializable
) di dichiarare che UID e deve essere cambiato ogni volta qualcosa cambia che colpisce la serializzazione (campi aggiuntivi, campi rimossi, cambiamento di ordine dei campi, ...). Il valore del campo viene controllato durante la deserializzazione e se il valore dell'oggetto serializzato non è uguale al valore della classe nella corrente VM, viene generata un'eccezione.
Si noti che questo valore è speciale in quanto è serializzato con l'oggetto anche se è statico, per le ragioni sopra descritte.