Get-put ilkesinin açıklaması


83

O'Reilly kitabını okudum, bu koyma ilkesini öğrendim .

  • Bir kullan extendssadece zaman joker olsun bir yapının dışına değerlerini.
  • Bir yapıya superyalnızca değerler koyduğunuzda joker karakter kullanın .
  • Ve ikiniz de bir yapı almak ve bir yapıya / yapıya koymak istediğinizde joker karakter kullanmayın.

İstisnalar şunlardır:

  • extendsJoker karakterle bildirilen bir türe null, her başvuru türüne ait olan değer dışında hiçbir şey koyamazsınız .

  • Her başvuru türünün süper türü olan supertür değeri dışında, joker karakterle bildirilen bir türden hiçbir şey elde edemezsiniz Object.

Bu kuralı derinlemesine keşfetmeme yardım eden var mı? Mümkünse lütfen bunları hiyerarşik bir şekilde belirtin.


4
+1: Birinin bir temel hakkında açıklama istediğini görmek her zaman güzel
Herkes

2
@Herkes, anladığım kadarıyla dorsal taraf yerine temel anlamda temelden mi bahsediyorsunuz?
Rich Seller

Yanıtlar:


167

Bir demet muz düşünün. Bu, Collection<? extends Fruit>belirli bir meyve türünün bir toplamı olduğu için - ama (bu bildiriden) ne tür bir meyveden oluştuğunu bilmiyorsunuz. Şunları yapabilirsiniz olsun ondan bir öğe ve kesinlikle bir meyve olacak biliyorum, ama olamaz eklemek buna - kesinlikle yanlış olur muz bir demet, bir elma eklemek çalışıyor olabilir. Sen edebilirsiniz eklemek nullbunun için geçerli bir değer olacağı gibi kendisine herhangi meyvenin tür.

Şimdi bir meyve tabağı düşünün. Bu a Collection<? super Banana>, çünkü "büyüktür" Banana(örneğin, Collection<Fruit>veya Collection<TropicalFruit>) bir tür koleksiyondur . Sen olabilir kesinlikle buna bir muz ekleyin, ancak kase bir öğeyi getirme eğer ne alırsınız bilmiyorum - bu iyi olabilir değil bir muz olun. Kesin olarak bildiğiniz tek şey, bunun geçerli (muhtemelen null) bir Objectreferans olacağıdır.

(Genel olarak, Java jenerikleri soruları için Java Generics SSS , atmanız muhtemel jeneriklerle ilgili hemen hemen her şeyin yanıtını içeren mükemmel bir kaynaktır.)


ancak <? extends Fruits> Koleksiyonundan bir meyve alırken, muz değil herhangi bir meyve alabilirsiniz. benzer şekilde, ona bir meyve koyarken, muz meyvelerine ait olmayan herhangi bir şeyi ekleyebilirsiniz
JavaResp

6
Java, Collection<? extends Fruit>tam olarak bu nedenle, null dışında herhangi bir şey eklemenizi engeller ve tam da bu nedenlerden dolayı, bir öğeyi getirmenin sonucunu açıkça atmanız gerekir.
Jon Skeet

@JonSkeet Bu aptalca bir soru olabilir, ancak hangi durumlarda hem add () hem de get () yöntemlerine "erişimin" olmaması yararlıdır? Demek istediğim, listeden bir nesne çıkarmak () için önce onu eklemelisin, değil mi? Ve tam tersi, eğer daha sonra alamazsanız neden eklersiniz?
Timmos

7
@Timmos: Bir şeyin bir değer ekleyebilmesi gerektiği için , tüm kodun bunu yapabilmesi gerektiği anlamına gelmez . Örneğin, kişi isimlerinin bir listesini görüntülemek için, sadece bir Collection<? extends Person>(veya daha büyük olasılıkla sadece bir Iterable<? extends Person>, ama ...) ihtiyacım olabilir. Bu koleksiyonu oluşturan kodun bir olması gerekebilir Collection<Employee>, ancak tüketen kod gerekmez.
Jon Skeet

5
@Timmos: Bu durumda "o" ile tam olarak ne kastettiğinizi söylemeniz gerekir ... ama evet, jenerik Java kuralları tür güvenliği sağlamak için tasarlanmıştır.
Jon Skeet
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.