2013-03-21 13 views
6

Ho finalmente provato a liberarmi di tutti quei nuovi avvisi del compilatore che Java 7 ha gentilmente generato. Ho lasciato questi due che non riesco a capire. C'è un modo per sbarazzarsi di loro senza sopprimerli?Alcuni avvisi di Java 7: come rimuoverli

Costruire un array di oggetti genericamente tipizzati (dove posso mettere una nella creazione array?):

static final int N = 10; 
//warning: [unchecked] unchecked conversion 
    static final Set<Widget>[] queued = new ConcurrentSkipListSet[N]; 
//required: Set<Widget>[] 
//found: ConcurrentSkipListSet[] 

varargs generici (sembra accadere quasi ovunque accetto varargs di un tipo generico):

class Foo<T> { 
//warning: [unchecked] Possible heap pollution from parameterized vararg type T 
    public void add(T... entries) { 
//where T is a type-variable: 
//T extends Object declared in class Foo 

BTW: ho già:

// Add many entries to the list. 
    public void add(List<T> entries) { 
    // ... 
    } 

    // Add a number of entries. 
    public void add(T... entries) { 
    // Make a list of them. 
    add(Arrays.<T>asList(entries)); 
    } 

risposta

1

generica creazione matrice:

static final ConcurrentSkipListSet<Widget>[] queued = newArray(N); 
// note: declare the most specific type for private objects 


@SafeVarargs 
static <E> E[] newArray(int length, E... array) 
{ 
    return Arrays.copyOf(array, length); 
} 

Come funziona - dal newArray è un metodo vararg, un argomento E[] array deve essere passata, quindi il corpo metodo ha accesso al tipo di E[]. Questo è teoricamente corretto, e se non c'è cancellatura, sarà totalmente sicuro al runtime. Con la cancellazione, abbiamo solo cancellato il tipo di E[] in fase di esecuzione, va bene, restituiamo anche lo stesso tipo cancellato.

+0

Wow !! Risolto entrambi i miei problemi in un colpo solo. Non capisco come 'newArray (N)' in realtà passi una matrice del tipo corretto a 'newArray', ma ti sbrighi il capo. BTW - L'ho regolato su 'static finale ConcurrentSkipListSet [] queued = DoubleBufferedList. > newArray (N);' per i miei test. – OldCurmudgeon

+0

perché non semplicemente 'statico finale ConcurrentSkipListSet [] queued = DoubleBufferedList.newArray (N);' – ZhongYu

+0

Perché quando ho rintracciato in quella forma mi ha dato un 'Object []' nel 2 ° parametro. Con il mio ho ottenuto un 'ConcurrentSkipListSet []' che mi sembra migliore. Mi rendo conto che è una differenza molto secondaria perché fondamentalmente sono entrambi "Oggetto []". – OldCurmudgeon

7

Per la prima:

static final Set<Widget>[] queued = new ConcurrentSkipListSet<>[N]; 

Prima di Java 7, avrebbe dovuto essere:

static final Set<Widget>[] queued = new ConcurrentSkipListSet<Widget>[N]; 

Tuttavia, si sono probabilmente meglio dichiarando questo come un ArrayList<Set<Widget>>. Generalmente, il mix di array e generici è un po 'difficile in Java.

static final List<Set<Widget>> queued = new ArrayList<>(); 
// or new ArrayList<Set<Widget>>(); 

quanto riguarda il secondo, vedere this thread. Sebbene tu possa sopprimere il messaggio, in realtà è un avvertimento su un pericolo reale. La linea di fondo di quel filo è che la cosa sicura da fare è di cambiare la vostra firma del metodo (e le chiamate corrispondenti) a:

class Foo<T> { 
    public void add(List<T> entries) { 
     . . . 

La questione è fondamentalmente lo stesso del primo: le matrici non si dovrebbe essere la creazione di di generici.

+0

Ho provato entrambi: ho riscontrato un errore: creazione di array generici in entrambi i casi. – OldCurmudgeon

+0

@OldCurmudgeon - Ho modificato la mia risposta un po '. Usa 'ArrayList >'. –

+0

Il tuo riferimento punta infine a una pagina Oracle che discute il problema, ma non vedo una soluzione lì. – OldCurmudgeon

2

Per risolvere il secondo, è necessario aggiungere @SafeVarargs alla dichiarazione del metodo.

Dal javadocs, questo è:

A programmer assertion that the body of the annotated method or constructor does not perform potentially unsafe operations on its varargs parameter. Applying this annotation to a method or constructor suppresses unchecked warnings about a non-reifiable variable arity (vararg) type and suppresses unchecked warnings about parameterized array creation at call sites.