Ne yapmanız gerektiğine bağlı. Bunun gibi bir şey yapmak istiyorsanız, sınırlı tür parametresini kullanmanız gerekir:
public <T extends Shape> void addIfPretty(List<T> shapes, T shape) {
if (shape.isPretty()) {
shapes.add(shape);
}
}
Burada bir List<T> shapes
ve bir var T shape
, bu nedenle güvenle yapabiliriz shapes.add(shape)
. Eğer ilan edilmişse List<? extends Shape>
, güvenli bir şekilde YAPAMAZSINIZadd
(çünkü bir List<Square>
ve a'ya sahip olabilirsiniz Circle
).
Dolayısıyla, sınırlı bir tür parametresine bir ad vererek, onu jenerik yöntemimizde başka bir yerde kullanma seçeneğine sahibiz. Elbette bu bilgiler her zaman gerekli değildir, bu nedenle tür hakkında çok fazla bilgi sahibi olmanız gerekmiyorsa (örneğin sizin drawAll
), o zaman sadece joker karakter yeterlidir.
Sınırlı tür parametresine tekrar başvurmasanız bile, birden çok sınırınız varsa sınırlı bir tür parametresi yine de gereklidir. İşte Angelika Langer'in Java Generics SSS'lerinden bir alıntı
Joker karakter sınırı ile tür parametresi sınırı arasındaki fark nedir?
Bir joker karakterin yalnızca bir sınırı olabilirken, bir tür parametresinin birkaç sınırı olabilir. Bir joker karakter, alt veya üst sınıra sahip olabilirken, tür parametresi için alt sınır diye bir şey yoktur.
Joker karakter sınırları ve tür parametresi sınırları genellikle karıştırılır, çünkü her ikisi de sınır olarak adlandırılır ve kısmen benzer sözdizimine sahiptir. […]
Sözdizimi :
type parameter bound T extends Class & Interface1 & … & InterfaceN
wildcard bound
upper bound ? extends SuperType
lower bound ? super SubType
Bir joker karakterin alt veya üst sınırı olmak üzere yalnızca bir sınırı olabilir. Joker karakter sınırları listesine izin verilmez.
Constrast'ta bir tür parametresinin birkaç sınırı olabilir, ancak bir tür parametresi için alt sınır diye bir şey yoktur.
Etkili Java 2. Sürüm, Madde 28'den alıntılar : API esnekliğini artırmak için sınırlı joker karakterler kullanın :
Maksimum esneklik için, üreticileri veya tüketicileri temsil eden girdi parametrelerinde joker türler kullanın. […] PECS, üretici- extends
, tüketici- super
[…]
Döndürme türleri olarak joker karakter türlerini kullanmayın . Kullanıcılarınız için ek esneklik sağlamak yerine, onları istemci kodunda joker karakter türleri kullanmaya zorlar. Uygun şekilde kullanıldığında, joker karakter türleri bir sınıfın kullanıcıları için neredeyse görünmezdir. Yöntemlerin kabul etmeleri gereken parametreleri kabul etmelerine ve reddetmeleri gerekenleri reddetmelerine neden olurlar. Sınıfın kullanıcısı joker türleri hakkında düşünmek zorunda kalırsa, muhtemelen sınıfın API'sinde bir sorun vardır .
PECS ilkesini uygulayarak şimdi addIfPretty
örneğimize geri dönebilir ve aşağıdakileri yazarak onu daha esnek hale getirebiliriz:
public <T extends Shape> void addIfPretty(List<? super T> list, T shape) { … }
Şimdi edebilir addIfPretty
, bir söylemek Circle
bir etmek, List<Object>
. Açıkçası bu tür güvenlidir, ancak orijinal beyanımız buna izin verecek kadar esnek değildi.
İlgili sorular
Özet
- Sınırlı tür parametreleri / joker karakterler kullanın, bunlar API'nizin esnekliğini artırır
- Tür birkaç parametre gerektiriyorsa, sınırlı tür parametresi kullanmaktan başka seçeneğiniz yoktur.
- tür bir alt sınır gerektiriyorsa, sınırlı joker karakter kullanmaktan başka seçeneğiniz yoktur
- "Üreticilerin" üst sınırı, "tüketicilerin" daha düşük sınırı vardır
- Dönüş türlerinde joker karakter kullanmayın