SORU
17 Mayıs 2012, PERŞEMBE


Belirsiz aşırı jenerik ve varargs yöntemleri java

Java işlev çağrıları belirsizlikler ile nasıl başa çıktıklarını anlamaya çalışıyorum. Aşağıdaki kodda, method çağrısı belirsiz, ama method2 değil!!!.

Her ikisi de belirsiz hissediyorum, ama neden bu derleme method çağrısı yorum var mı? Neden method2 belirsiz olarak iyi mi?

public class A {
    public static <K> List<K> method(final K arg, final Object... otherArgs) {
        System.out.println("I'm in one");
        return new ArrayList<K>();
    }

    public static <K> List<K> method(final Object... otherArgs) {
        System.out.println("I'm in two");
        return new ArrayList<K>();
    }

    public static <K, V> Map<K, V> method2(final K k0, final V v0, final Object... keysAndValues) {
        System.out.println("I'm in one");
        return new HashMap<K,V> ();
    }

    public static <K, V> Map<K, V> method2(final Object... keysAndValues) {
        System.out.println("I'm in two");
        return new HashMap<K,V>();
    }

    public static void main(String[] args) {
        Map<String, Integer> c = A.method2( "ACD", new Integer(4), "DFAD" );
        //List<Integer> d = A.method(1, "2", 3  );
    }
}

EDİT: Bu yorum geldi: IDE Bir dizi rapor olarak belirsiz iki - SDE Eclipse şimdiye kadar. Ancak, komut satırından iyi/maven derler.

CEVAP
18 Mayıs 2012, Cuma


method1 metho2 daha belirli olup olmadığını test etmek için sezgisel bir yöntem method1 ile aynı parametreleri method2 çağırarak uygulanabilir olup olmadığını görmek için

method1(params1){
    method2(params1);   // if compiles, method1 is more specific than method2
}

Eğer varargs ise, 2 yöntem parametreler aynı sayıda olması için bir sırasında genişletmek için ihtiyacımız olabilir.

Hadi örnek method()ilk iki s kontrol edin

<K> void method_a(K arg, Object... otherArgs) {
    method_b(arg, otherArgs);   //ok L1
}
<K> void method_b(Object arg, Object... otherArgs) { // extract 1 arg from vararg
    method_a(arg, otherArgs);   //ok L2
}

(dönüş türleri çıkarılana kadar belirleyici özgüllük,) kullanılmaz

Derleme, bu nedenle her diğer, belirsizlik dolayısıyla daha özeldir. Aynı method2()ler için de geçerli, birbirimize daha özeldir. method2() Bu nedenle çağrı belirsiz ve derleme olmamalı; aksi halde derleyici bir hata.


Spec söylüyor; ama bu doğru mu? Kesinlikle, method_a method_b daha özel görünüyor. K yerine somut bir tipi var aslında

void method_a(Integer arg, Object... otherArgs) {
    method_b(arg, otherArgs);   // ok
}
void method_b(Object arg, Object... otherArgs) {
    method_a(arg, otherArgs);   // error
}

o zaman sadece method_a method_b değil, tam tersi daha özeldir.

Tutarsızlık tür kesmesi büyüsü ortaya çıkar. L1/L2 derleyici tür tartışmalar gerçekleştirip dener çok açık tür argümanlar olmadan genel bir yöntemi çağırır.hedeftür çıkarımı algoritması türü değişkenleri bulmakkodu derler! Merak L1 ve L2 derleme yok. L2 aslında this.<Object>method_a(arg, otherArgs) olmak anlaması

Tür kesmesi programcı ne istediğini tahmin etmeye çalışır, ama sanırım bazen yanlış olmalı. Gerçek niyetimiz aslında

<K> void method_a(K arg, Object... otherArgs) {
    this.<K>method_b(arg, otherArgs);   // ok
}
<K> void method_b(Object arg, Object... otherArgs) {
    this.<K>method_a(arg, otherArgs);   // error
}

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Doc Adams

    Doc Adams

    20 HAZİRAN 2007
  • dougownsall

    dougownsall

    7 EKİM 2007
  • MagicofRahat

    MagicofRahat

    13 Temmuz 2007