Java 8'deki yeni lambda gösteriminin tanıtılması (örneğin bu makaleye bakınız ) bir tür çıkarım gerektiriyor mu?
Öyleyse, yeni tür sistemi Java dilini bir bütün olarak nasıl etkiler?
Java 8'deki yeni lambda gösteriminin tanıtılması (örneğin bu makaleye bakınız ) bir tür çıkarım gerektiriyor mu?
Öyleyse, yeni tür sistemi Java dilini bir bütün olarak nasıl etkiler?
Yanıtlar:
Cırcır ucube cevabında ve yorum başlığında oldukça fazla yanlış bilgi var . Yorum çok küçük olduğu için burada cevap olarak cevap vereceğim. Ayrıca, sonuçta bu bir cevap olduğundan, orijinal soruyu da cevaplamaya çalışacağım. (Ancak tip sistemler konusunda uzman olmadığımı unutmayın.)
İlk olarak, asıl soruya verilen kısa cevaplar Evet ve Hayır'dır. Evet, Java 8, Java 7'den oldukça daha fazla tür çıkarımına sahip olacaktır ve Hayır, Java 8'de "yeni" bir tür sistem yoktur, ancak bazı küçük değişiklikler olsa da .
Java 8 hala statik olarak yazılacak ve sınıflar ve arayüzler arasında hala ikilik olacak. İşlev türleri gibi yeni türler yoktur. Bir lambda tipi, esasen, tek bir soyut yöntemle sıradan bir arayüz olan "fonksiyonel bir arayüz" dür.
Arabirimler artık varsayılan yöntemler biçiminde koda sahip olabilir, ancak sınıfların tek miras ve çoklu arabirim mirası modeli aynı kalır. Elbette, varsayılan yöntemlerin varlığında yöntem çözümleme kuralları gibi bazı ayarlamalar vardır, ancak temelleri değişmez.
Tür çıkarımı ile çıkarılan herhangi bir tür açıkça yazılabilir. Kullanmak için mandal ucube 'in, örneğin,
Collections.<MyClass>sort(list, (a, b) -> { return a.order - b.order; });
temelde şeker
Collections.<MyClass>sort(list,
(Comparator<MyClass>)((MyClass a, MyClass b) -> { return a.order - b.order; }));
Bu yüzden sparkleshy'nin "tip çıkarımı, tip sisteminin genişletilmesini gerektirmez" ifadesi temel olarak doğrudur.
Fakat sözdizimsel şekere geri dönmek için, bir lambda ifadesinin adsız bir iç sınıf için sözdizimsel bir şeker olmadığı ifadesini tekrar edeceğim . Cırcır kaçık bir lambda ifade Anonim iç sınıf örnekleme çevrilir ve Sparkleshy sadece bir lambda bu yeniden ileri sürülmektedir belirtti olan Anonim iç sınıf için sözdizimsel şeker, ama bu açıklamalar yanlıştır. Muhtemelen eski bilgilere dayanmaktadır. Erken lambda uygulamaları bu şekilde lambda uyguladı, ancak işler değişti.
Lambda ifadeleri iç sınıflardan anlamsal olarak farklıdır ve iç sınıflardan farklı şekilde uygulanırlar.
Lambda ifadeleri iç sınıflardan birkaç şekilde anlamsal olarak farklıdır. Bir lambda ifadesini değerlendirmek için her seferinde yeni bir örnek oluşturmak gerekmez. Ayrıca farklı yakalama anlambilimlerine sahiptirler, örneğin bunu farklı yakalarlar . Bir iç sınıfta, bu iç sınıf örneğidir, oysa bir lambda, bu etrafını saran örnektir. Aşağıdakileri göz önünde bulundur:
public class CaptureThis {
void a(Runnable r) { r.run(); }
void b() {
a(new Runnable() { public void run() { System.out.println(this); }});
a(() -> System.out.println(this));
}
public String toString() { return "outer"; }
public static void main(String[] args) { new CaptureThis().b(); }
}
Yeni bir JDK 8 lambda yapısında ( b69 kullandım ) çıktı aşağıdaki gibi olacak:
CaptureThis$1@113de03
outer
Ayrıca, lambda ifadeleri iç sınıflardan tamamen farklı bir şekilde uygulanır. Demonte çıktısını karşılaştırırsanız, iç sınıf kodunun açıkça yaratma ile derlendiğini ve bir CaptureThis kurucusuna çağrıldığını görürsünüz, bu $ 1 iken, lambda ifadesi belirtilmemiş bir Runnable yoluyla bir Runnable yöntemini tedarik eden bir inokimyasal komuttan derlenir. Bunun nasıl çalıştığının ve nedeninin tam bir açıklaması için bkz. Brian Goetz 'JavaOne 2012 talk Lambda: Kaputun Altına Bir Göz .
this
ileMyClass.this