2016-04-14 21 views
3

JLS 15.27.2 belgesine göre, lambda gövdesi çevre bağlamla aynı kapsamdadır ve lambda tarafından uygulanan arabirimden varsayılan yöntemlerin neden belirli bir neden olup olmadığını bilmek isterim ' t vücutta mevcut mu? Bu kısıtlama bazı optimizasyonları mümkün kılıyor mu, yoksa aşırı yükleme kurallarını basit tutmak mı?Lambda ifadesinde varsayılan yöntemleri kullanma

Günümüzde bazı Java 8 API'sini prototipliyordum ve bu sınırlamayı vurduğumda oldukça hayal kırıklığına uğradım çünkü varsayılan yöntemleri kullanmak bu API'yi çok zarif ve müdahaleci olmayan bir şekilde uygulamamı sağladı.

Aynı zarafetin elde edilmesi, statik bir içe aktarma gerektirerek az çok olasıdır, ancak ad alanının "kirletilmesi" ile sonuçlanır.

Bu kısıtlamanın kaldırılması ihtimali var mı?

+0

Kısa bir örnek, – AdamSkywalker

+1

ile ilgili ne hakkında konuştuğunuzu anlamama yardımcı olabilir (yinelenmese de): http://stackoverflow.com/q/33108540/3973077 –

+1

“* lambda gövdesi aynı çevreleyen bağlamda * ”zaten kapsamda sahte 'varsayılan' yöntemleri olmadığını ima eder. Tabii ki, bu ad çözümleme kurallarını çok basitleştirir. Ve hepsi de mantraya doğru kaymaktadır “* lambda ifadeleri iç sınıflar için sözdizimsel şeker değildir.”… Ayrıca bakınız [burada] (http://stackoverflow.com/a/31491773/2711488) – Holger

cevap

3

Varsayılan yöntemler lambda için geçerli değildir, çünkü lambda henüz işlevsel bir türe atanana kadar bir tür verilmemiştir. Örneğin lambda

s -> s.isEmpty() 

bir java.util.function.Predicate veya com.google.common.base.Predicate atanabilir. Bu nedenle, java.util.function.Predicate'a doğrudan atama yoluyla java.util.function.Predicate'a doğrudan atama yapana kadar java.util.function.Predicate'un varsayılan yöntemlerine erişim sağlayamaz, java.util.function.Predicate parametresi olarak lambda'yı döndürerek, dönüş türü java.util.function.Predicate olan bir işlevden döndürür. ya da sadece böyle bir java.util.function.Predicate bunu döküm: bir int değeri boks benzer ediliyor düşünmek

((Predicate<String>) s -> s.isEmpty()).negate(); // negate is a default method on Predicate 

Tek yön. Integer adlı kullanıcının yöntemleri tamsayı bir tamsayı değerinde çağrılmaz, ancak tamsayı değeri Integer türüne atandığında, yöntemlerini çağırabilir.

+1

Peki bunun bir neden olduğunu görmüyorum. Derleyicinin nasıl uygulandığını bilmiyorum ama lambda türünün LHS'den çıkarılmasından dolayı derleyici lambda gövdesini kontrol ettiğinde türü zaten bilmelidir –

+2

Dereceni görüyorum ve derleyiciyi savunmak istemiyorum. FWIW, benim anlayışım, bir lambda imzasız bir bedendir ve fonksiyonel bir arayüz, bir bedeni olmayan bir imzandır ve bu ikisi birleştirilinceye ya da fiili bir fonksiyon üretilinceye kadar atanmaz. Umarım yardımcı olur. –

İlgili konular