2011-01-20 14 views
14

Ho una domanda perché sto diventando un po 'confuso (o forse non sto notando qualcosa di ovvio). Diciamo che ho un po 'di codice sorgente che contiene un sacco di classi che contengono un gran numero di campi statici definiti come questo:@SuppressWarnings ("serial")

public final class ConverterTYPE { 
    private final static HashMap<String, Byte> STRING_MAP = new HashMap<String, Byte>() { 
     { 
      put("A", new Byte((byte)12)); 
      put("B", new Byte((byte)13)); 
     } 
    }; 

} 

Come tutti sappiamo, i campi statici non stanno per essere serializzato.

Tuttavia, Java (ed Eclipse) lamentano che "la classe serializzabile non dichiara un campo seriale serialVersionUID finale di tipo lungo". Perché non possono notare che la statica non verrà serializzata?

E la prossima domanda: sarebbe una soluzione corretta a questo problema per utilizzare @SuppressWarnings("serial") per sbarazzarsi di tutti questi avvertimenti?

EDIT:

Nessuna delle mie classi implementa l'interfaccia Serializable (o nessuna delle loro superclassi). E Eclipse punta a HashMap<String, Byte> con i suoi avvisi. Perché non rileva che è un campo statico?

+2

Solo così sei consapevole - HashMap implementa l'interfaccia Serializable. Dato che estendi HashMap in una classe anonima, anche la tua classe anonima implementa anche Serializable. – Numeron

+1

Off-topic: https: //blog.jooq.org/2014/12/08/dont-be-clever-the-double-curly-braces-anti-pattern/ –

risposta

20

Solo perché quel campo non può essere serializzato non significa che la cosa a cui fa riferimento non verrà mai serializzata da solo! Qualcuno/altra cosa potrebbe ottenere un riferimento a tale mappa e provare a serializzarlo direttamente, o usarlo come membro di un'istanza in una classe serializzabile, ecc. Lo vedo come privato, ma assicurandosi che non sarà mai accessibile al di fuori dell'attuale classe o insieme a un membro di istanza è oltre la portata del compilatore (e impossibile con la riflessione intorno comunque.)

una possibile soluzione è quella di evitare semplicemente che sottoclasse anonima w/stile di inizializzazione tutti insieme e fare questo:

private final static HashMap<String, Byte> STRING_MAP = new HashMap<String, Byte>(); 

static { 
    STRING_MAP.put("A", new Byte((byte)12)); 
    STRING_MAP.put("B", new Byte((byte)13)); 
} 

Il risultato è quasi identico nella maggior parte dei casi e il codice non è disseminato di classi anonime.

+1

Vorrei aggiungere che nove volte su dieci, le raccolte inizializzate staticamente come questa sono intese essere immutabili. In tal caso, la libreria Google Collections ha una bella classe ImmutableMap che puoi usare: 'ImmutableMap.of (" A ", (byte) 12," B ", (byte) 13);'. C'è anche un 'ImmutableMap. builder() ', necessario per> 5 elementi. – yjo

16

Tuttavia, Java (ed Eclipse) si lamenta che "la classe serializzabile non dichiara un campo seriale serialVersionUID finale di tipo lungo". Perché non possono notare che la statica non verrà serializzata?

Il messaggio di errore e il fatto di avere una variabile membro finale statica nella classe (almeno, è così che interpreto la descrizione) non hanno nulla a che fare l'uno con l'altro.

La classe implementa l'interfaccia Serializable oppure una delle superclassi della classe lo fa. Quindi il compilatore nota che la tua classe è serializzabile. Le classi serializzabili devono avere un campo finale statico chiamato serialVersionUID che viene utilizzato per il controllo delle versioni quando si serializzano le istanze della classe.

L'utilizzo dell'annotazione @SuppressWarnings("serial") rende il compilatore inattivo su un numero mancante serialVersionUID. Quindi sì, è possibile utilizzarlo per sbarazzarsi del messaggio di avviso, ma una soluzione migliore è di impedire alla classe di implementare Serializable (direttamente o indirettamente) se non è destinata alla serializzazione.

+0

Nessuna delle mie classi implementa un'interfaccia Serializable (o nessuna delle loro superclassi). – Lukasz

+1

@Lukas sei sicuro? Com'è la tua gerarchia di classi? – Jesper

+0

Eclipse punta a: HashMap Lukasz

Problemi correlati