2014-08-30 15 views
20

Ho una sorta di metodo di util per trasformare un varargs di un tipo in un array di questo tipo - sembra che questo:Questo uso di vararg è sicuro?

public K[] array(K... ks) { 
    return ks; 
} 

Il caso d'uso è così che invece di definire una matrice quando si chiama un metodo che richiede un array, puoi semplicemente fare array (val1, val2, val3).

Tuttavia, IntelliJ mi dà avvisi di inquinamento heap. Capisco cosa significa in una certa misura, ma non ho molta esperienza con le specifiche - quindi, vorrei sapere se posso aggiungere @SafeVarargs e se questo metodo è effettivamente sicuro.

IntelliJ dice:

Problema sinossi possibile inquinamento mucchio di parametri di tipo vararg alla linea 249

risoluzione dei problemi Assicurarsi finale e annotare come @SafeVarargs

K è dichiarato come il digitare il parametro di una classe, insieme a V.

+13

IMO non occorre tale metodo, basta usare 'Qualunque sia [] = {whateverArray val1, val2, val3, ...};' –

+0

Puoi dare * * dettagli esatti del warning inquinamento mucchio? E dove è stato dichiarato il parametro di tipo 'K'? –

+0

@Luiggi, sì, ma è un'utilità. 'K [] keys = {key1, key2, key3}; object.method (keys); 'vs' object.method (array (key1, key2, key3)); '- il secondo è molto più facile da scrivere, specialmente quando lo fai molto. – DziNeIT

risposta

24

No, Non è sicuro - se chiamato da un altro metodo che sta usando i generici. Ecco un esempio completo che sembra va bene, ma genera un'eccezione:

class Utility<K> { 
    public K[] array(K... ks) { 
     return ks; 
    } 

    public K[] otherMethod(K k1, K k2) { 
     return array(k1, k2); 
    } 
}  

class Test { 
    public static void main(String[] args) throws Exception { 
     Utility<String> util = new Utility<String>(); 
     // Bang! 
     String[] array = util.otherMethod("foo", "bar"); 
    } 
} 

Quando il compilatore genera il bytecode per otherMethod, è non può creare un array del tipo giusto di passare in array, perché non conosce il tipo di K. A causa della cancellazione dei caratteri, crea semplicemente un valore Object[] con i valori. Quindi, nel main, c'è un cast nascosto dal risultato di otherMethod a String[] ... e che non riesce al momento dell'esecuzione.

Se si chiama array direttamente dal codice che davvero conosce i tipi di argomenti, allora va bene, perché la matrice implicitamente creato sarà del tipo giusto.

+0

grazie. fino a quando questa è l'unica (all'interno della ragione) situazione che potrebbe causare un problema, dovrebbe andare bene per quello che sto facendo. – DziNeIT

+3

Usare la vera cautela qui, @DziNeIT. Se è solo una follia e tu sei l'unica persona che usa questo codice, allora vai avanti. So quale sarebbe la mia opinione se mi imbattessi in qualcosa di simile, comunque. È una buona domanda con una risposta altrettanto buona, però. :) – TEK

0

Si potrebbe semplicemente dire al metodo come convertire nell'array appropriato. Un modo che ho trovato è stato quello di passare l'array nel metodo con le variabili, e quindi copiarlo.

public K[] otherMethod(K[] parent, K k1, K k2) { 
    List<K> list = new ArrayList<K>(); 
    Collections.addAll(list, array(k1, k2)); 
    list.toArray(parent); 
    return parent; 
} 

Ora l'uscita dipende dal metodo di Collections.toArray(), che restituisce null se non c'è abbastanza spazio nella matrice, o se c'è spazio extra i valori inutilizzati sarà nullo.

class Test { 
    public static void main(String[] args) throws Exception { 
     Utility<String> util = new Utility<String>(); 
     String[] array = util.array("one", "two", "three"); 
     array = util.otherMethod(array, "x", "y"); 
     printArr(array); // prints: x y null 

     Utility<Integer> util2 = new Utility<Integer>(); 
     Integer[] intarray = util2.otherMethod(new Integer[1], 1, 2); 
     printArr(intarray); // prints: null 
     Integer[] intarray = util2.otherMethod(new Integer[2], 1, 2); 
     printArr(intarray); // prints: 1 2 
    } 

    static void printArr(Object[] objArr) { 
     for (Object o:objArr) System.out.print(o+"\t"); 
    } 
} 
Problemi correlati