varargs vararg parametros indefinidos argumentos java generics variadic-functions

java - parametros - vararg kotlin



Java desmarcado: creación de matriz genérica no seleccionada para el parámetro varargs (3)

He configurado Netbeans para que muestre advertencias no verificadas en mi código Java, pero no entiendo el error en las siguientes líneas:

private List<String> cocNumbers; private List<String> vatNumbers; private List<String> ibans; private List<String> banks; ... List<List<String>> combinations = Utils.createCombinations(cocNumbers, vatNumbers, ibans);

Da:

[unchecked] unchecked generic array creation for varargs parameter of type List<String>[]

Fuente del método:

/** * Returns a list of all possible combinations of the entered array of lists. * * Example: [["A", "B"], ["0", "1", "2"]] * Returns: [["A", "0"], ["A", "1"], ["A", "2"], ["B", "0"], ["B", "1"], ["B", "2"]] * * @param <T> The type parameter * @param elements An array of lists * @return All possible combinations of the entered lists */ public static <T> List<List<T>> createCombinations(List<T>... elements) { List<List<T>> returnLists = new ArrayList<>(); int[] indices = new int[elements.length]; for (int i = 0; i < indices.length; i++) { indices[i] = 0; } returnLists.add(generateCombination(indices, elements)); while (returnLists.size() < countCombinations(elements)) { gotoNextIndex(indices, elements); returnLists.add(generateCombination(indices, elements)); } return returnLists; }

¿Qué está yendo exactamente mal y cómo lo solucionaría, ya que supongo que dejar advertencias sin marcar en el código no es una buena idea?

Se me olvidó mencionar, pero estoy usando Java 7.

Editar : También veo ahora que el método tiene lo siguiente:

[unchecked] Possible heap pollution from parameterized vararg type List<T> where T is a type-variable: T extends Object declared in method <T>createCombinations(List<T>...)


¿Cómo se trata de suprimir la advertencia?

@SuppressWarnings("unchecked")


Como mencionó anteriormente janoh.janoh, varargs en Java es solo un azúcar sintáctico para matrices más la creación implícita de una matriz en el sitio llamante. Asi que

List<List<String>> combinations = Utils.createCombinations(cocNumbers, vatNumbers, ibans);

es en realidad

List<List<String>> combinations = Utils.createCombinations(new List<String>[]{cocNumbers, vatNumbers, ibans});

Pero como sabrá, la new List<String>[] no está permitida en Java, por razones que han sido cubiertas en muchas otras preguntas, pero principalmente tienen que ver con el hecho de que las matrices conocen su tipo de componente en tiempo de ejecución, y verifican tiempo de ejecución si los elementos agregados coinciden con su tipo de componente, pero esta verificación no es posible para tipos parametrizados.

De todos modos, en lugar de fallar, el compilador aún crea la matriz. Hace algo similar a esto:

List<List<String>> combinations = Utils.createCombinations((List<String>[])new List<?>[]{cocNumbers, vatNumbers, ibans});

Esto es potencialmente inseguro, pero no necesariamente inseguro. La mayoría de los métodos varargs simplemente iteran sobre los elementos varargs y los leen. En este caso, no le importa el tipo de tiempo de ejecución de la matriz. Este es el caso con su método. Como está en Java 7, debe agregar la anotación @SafeVarargs a su método, y ya no recibirá esta advertencia. Esta anotación básicamente dice que a este método solo le interesan los tipos de los elementos, no el tipo de la matriz.

Sin embargo, hay algunos métodos varargs que sí usan el tipo de tiempo de ejecución de la matriz. En este caso, es potencialmente inseguro. Es por eso que la advertencia está ahí.


Porque el compilador de Java usa una creación de matriz implícita para varargs, y java no permite una creación de matriz genérica (porque el argumento de tipo no es reificable).

El código siguiente es correcto (estas operaciones están permitidas con matrices), por lo que se necesita una advertencia sin marcar:

public static <T> List<List<T>> createCombinations(List<T> ... lists) { ((Object[]) lists)[0] = new ArrayList<Integer>(); // place your code here }

Vea una explicación completa here