2014-08-30 34 views
20

Ben o tip bir diziye bir türde bir varargs dönüştürmeye util yöntemin bir tür var - bu şuna benzer:Bu varargs güvenli kullanım mı?

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

kullanım durumu böyledir yerine bir yöntem çağrılırken bir dizi tanımlayan bir dizi gerektirir, sadece dizi yapabilirsiniz (val1, val2, val3). Bununla birlikte, IntelliJ bana yığın kirliliği uyarıları veriyor. Bunun ne anlama geldiğini anlıyorum, ama özellikleriyle çok fazla tecrübem yok - bu yüzden, @SafeVarargs ekleyip ekleyemediğimi ve bu yöntemin gerçekten güvenli olup olmadığını bilmek istiyorum.

IntelliJ diyor ki: hattında parametreli vararg türünden

Sorun sinopsis Olası yığın kirliliği 249

Sorun çözünürlüğü nihai yapın ve @SafeVarargs

K olarak bildirilmiş olması açıklama Bir sınıfın parametre parametresi ile birlikte V.

+13

IMO böyle bir yöntem gerekmez, sadece kullanmak 'ne olursa olsun [] whateverArray = {val1, val2, VAL3, ...};' –

+0

Eğer yığın kirliliği uyarısı * kesin * detay verir misin? Ve k tipi parametre parametresi nerede ilan edildi? –

+0

@Luiggi, evet, ama bu bir yardımcı program. 'K [] tuşları = {key1, key2, key3}; object.method (keys); 'vs' object.method (dizi (key1, key2, key3)); '- ikincisi, özellikle çok yaptığınız zaman yazmak daha kolaydır. – DziNeIT

cevap

24

Hayır, Güvenli değil - jenerik kullanan başka bir yöntemden çağrılırsa. Çünkü derleyici otherMethod için bytecode oluşturur

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

, bu array geçmesine sağ türden bir dizi oluşturamıyor edebilirsiniz: İşte tamam görünüyor tam bir örnek, ama bir istisna atar K'un türünü bilmiyor. Tür silme nedeniyle, yalnızca değerlerle bir Object[] oluşturur. Yani main'da, otherMethod sonucu String[] ... 'dan bir gizli yayın var ve bu, yürütme zamanında başarısız oluyor. Eğer gerçekten parametre tiplerini bilir kodundan doğrudan array ararsanız Dolaylı oluşturulan dizi sağ tipte olacaktır çünkü

, o zaman, sorun yok.

+0

teşekkür ederim. Bu, bir soruna neden olabilecek tek (mantık içinde) durum olduğu sürece, yaptığım şey için iyi olmalıdır. – DziNeIT

+3

Gerçek dikkati burada kullanın, @DziNeIT. Bu sadece bir folikse ve bu kodu kullanan tek kişi sizsiniz, o zaman devam edin. Bununla birlikte, böyle bir şeye rastladığımda fikrimin ne olacağını biliyorum. Yine de, eşit derecede iyi bir cevapla iyi bir soru. :) – TEK

0

Sadece yönteminize uygun diziye nasıl dönüştürüleceğini söyleyebilirsiniz. Bulduğum bir yol, diziyi değişkenlerle birlikte yönteme aktarmak ve daha sonra ona kopyalamaktı.

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

Şimdi çıkış var dizide yeterli alan olmadığı veya fazladan boşluk varsa kullanılmayan değerleri boş olacaksa null döndürür Collections.toArray() yöntemine bağlıdır.

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