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
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
}
Varargs Belirsiz Ara Java...
Jenerik Java: PECS Nedir?...
Set kullanımı(önerilen|Maksimum|Minimu...
Liste<Köpek> Listenin alt<Hay...
Neden't statik Java yöntemleri ge...