Java denetlenmemiş: varargs parametresi için denetlenmemiş genel dizi oluşturma


112

Netbeans'i Java kodumda kontrol edilmemiş uyarılar gösterecek şekilde ayarladım, ancak aşağıdaki satırlarda hatayı anlayamıyorum:

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);

verir:

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

Yöntem kaynağı:

/**
 * 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;
}

Tam olarak ters giden nedir ve kodda kontrol edilmeyen uyarıları bırakmak iyi bir fikir olmadığını düşündüğüm için bunu nasıl düzeltebilirim?

Bahsetmeyi unuttum ama Java 7 kullanıyorum.

Düzenleme : Ayrıca artık yöntemin aşağıdakilere sahip olduğunu görüyorum:

[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>...)

17
Başka ne yaparsan yap, Java'da yeni oluşturulmuş bir int dizisini 0'larla başlatmana gerek yok ...
Thomas Mueller

1
@ThomasMueller İyi yakala
skiwi

Yanıtlar:


166

Janoh.janoh'un yukarıda bahsettiği gibi, Java'daki varargs diziler için sadece sözdizimsel bir şekerdir ve ayrıca çağıran sitede örtük bir dizinin oluşturulmasıdır. Yani

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

aslında

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

Ancak bildiğiniz gibi, new List<String>[]diğer birçok soruda ele alınan nedenlerden ötürü Java'da izin verilmez, ancak esas olarak dizilerin çalışma zamanında bileşen türlerini bilmeleri ve eklenen öğelerin bileşeniyle eşleşip eşleşmediğini çalışma zamanında kontrol etmeleriyle ilgilidir. tür, ancak parametreli türler için bu denetim mümkün değildir.

Her neyse, başarısız olmak yerine, derleyici yine de diziyi yaratır. Şuna benzer bir şey yapar:

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

Bu potansiyel olarak güvensizdir, ancak mutlaka güvensiz değildir. Çoğu varargs yöntemi, varargs öğeleri üzerinde yineleme yapar ve bunları okur. Bu durumda, dizinin çalışma zamanı türü umurunda değildir. Sizin yönteminizde durum budur. Java 7'de olduğunuz için, @SafeVarargsaçıklamayı yönteminize eklemelisiniz ve artık bu uyarıyı almayacaksınız. Bu ek açıklama temelde, bu yöntemin dizinin türü ile değil, yalnızca öğelerin türleriyle ilgilendiğini söyler.

Ancak, dizinin çalışma zamanı türünü kullanan bazı varargs yöntemleri vardır. Bu durumda potansiyel olarak güvensizdir. Bu yüzden uyarı var.


16
Yalnızca SafeVarag'lerden bahsettiğiniz için değil, ne zaman kullanabileceğimizi bize bildirdiğiniz için teşekkür ederiz.
KitsuneYMG

12
Herkes için hemen açık değilse (benim için olmadığı gibi), Javadocs @SafeVarargs, güvenli olmayan bir yöntem örneğine sahiptir. Docs.oracle.com/javase/7/docs/api/java/lang/SafeVargs .html
michiakig

3
Yani @SafeVarargssenin yöntem zaman kullanılabilir sadece tüketir dizinin elemanlarını ve olmayan (ve asla) üreten gelmez diziye koymak unsurlar? Dizi bağımsız değişkenini başka yöntemlerle değiştirilebilecek bir alana atarsanız özel dikkat gösterilmelidir, çünkü üzerinde gerçekleştirilen güvenli olmayan işlemlerin olmadığını belirlemek önemsiz olmayabilir.
neXus

13

Java derleyicisi vararg'lar için örtük bir dizi oluşturma kullandığından ve java genel bir dizi oluşturulmasına izin vermediğinden (çünkü tür bağımsız değişkeni yeniden yapılandırılamaz).

Aşağıdaki kod doğrudur (bu işlemlere dizilerde izin verilir), bu nedenle kontrol edilmeyen uyarı gereklidir:

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

Burada kapsamlı bir açıklamaya bakın

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.