Sayı

2016-03-22 13 views
1

Yani, aşağıdaki iki sınıfları:Sayı

Class A { } 
Class B extends A { } 
Class C extends A { } 

Ve aşağıdaki yöntemi: Artık

public void foo(Collection<A> bar) { 
    List<A> listA = new ArrayList<>(); 

    for(A a : bar) { 
     //a and anotherA are both of the same subtype of A 
     A anotherA = getAnotherA(a); 
     listA.add(anotherA); 
    } 

    bar.clear(); 
    bar.addAll(listA); 
} 

, bunu aramaya çalışıyorum yöntem iki ayrı yol, ancak dökümün düzgün çalışmasını sağlayamıyorum ... Umarım sadece küçük bir şeye bakıyorum.

Yolu 1:

Yani, burada iki yolu bunu arıyorum olan

A obj = ...; 
Field field = //get field representing a collection of sub-type of A 
Collection<A> collection = field.get(...); 
foo(collection); 

yolu 2:

B obj = ...; 
Set<C> setOfC = b.getSetOfC(); 
foo(setOfC); 

Ben girişimleri döküm sayısız denedi, ama yapamıyorum derlemek için görünüyor! Örneğin, 2 yolunda setOfC'u Set<A>'a çevirmeyi denedim, ancak bir sınıf döküm istisnası alıyorum. bar'u Collection<? extends A>'a göndermeye çalıştım ancak bar.addAll (..) başarısız oluyor. Foo'ya jenerik eklemeyi denedim, ancak hatalar da aldım. Yol 1'de, collection'u Collection<? extends A>'a göndermeye çalıştım, ancak yine de şansım yok.

cevap

3

Bir Set bir Collection olmasına rağmen bir Collection<A> bekliyor bir yönteme içine Set<C> geçemez ve Java'nın jenerik değişmez çünkü rağmen bir C, bir A olduğunu.

foo yönteminde, A üst sınırıyla bir tür parametresi tanıtabilirsiniz. Sonra yöntem boyunca type parametresini kullanabilirsiniz. Bu, A'un aynı alt türünün kullanılmasını sağlayacaktır.

public static <T extends A> void foo(Collection<T> bar) { 
    List<T> listA = new ArrayList<>(); 

    for(T a : bar) { 
     //a and anotherA are both of the same subtype of A 
     T anotherA = getAnotherA(a); 
     listA.add(anotherA); 
    } 

    bar.clear(); 
    bar.addAll(listA); 
} 

Yorumunuz a ve anotherA aynı tipte olduğunu belirtmek görünüyor, bu nedenle bu sizin için derlemek gerekir. Aksi halde, getAnotherA yönteminin bazı çalışmalara gereksinimi vardır, böylece C'da bir C ve A döndüremezsiniz. Bu sınıfları varsa

+0

teşekkür gibi çoğu! Bunu doğru bir yaklaşım olacağını düşündüğümden daha önce denediğimi düşündüm, ama bir hatayı almayı hatırla. Sadece tekrar denedim ve işe yaradı! – user972276

0

:

Class YourA { } 
Class YourB extends YourA { } 
Class YourC extends YourA { } 

senin yöntemin imza

public <G extends YourA> void foo(Collection<G> bar) {...}