2016-06-22 38 views
8

Java lambdas ve yöntem referansları davranışı hakkında biraz kafam karışık. . Eski için, bu kodu vardır:Eşdeğer lambda ifadesi ve yöntem referansı, statik alan değerini yakalarken neden farklı davranıyor?

import java.util.function.Consumer; 

public class Main { 

    private static StringBuilder sBuilder = new StringBuilder("1"); 

    public static void main(String[] args) { 
     Consumer<String> consumer = s -> sBuilder.append(s); 
     sBuilder = new StringBuilder("2"); 
     consumer.accept("3"); 
     System.out.println(sBuilder); 
    } 

} 

Çıktı:

23 

Biz değiştirirseniz beklendiği gibi çalışır, ancak

s -> sBuilder.append (ler)

with

sB uilder ::

ekler çıkış olacaktır:

2 

nasıl bu açıklamaya Sana fikir var mı? Bu aynı şey değil mi? Teşekkürler.

+1

[Bu] (http://stackoverflow.com/questions/30514995/what-is-the-difference-between-a-lambda-and-a-method-reference-at-a mi -runtime-leve) çoğaltmak için çok kıvrık? –

+0

@SotiriosDelimanolis :) yararlı referanslar için teşekkür biraz teşekkür Başka bir deyişle – j2esu

cevap

10

Lambda ifadesinde, sBuilder alanı yakalanır, ancak değerlendirilmez. Sadece ilgili fonksiyon arayüzü metodu çalıştırıldığında değerlendirilecektir. Bu noktada, sBuildersBuilder alanı Consumer örneği üretmek için hemen değerlendirilir, yöntem, referans olarak

sBuilder = new StringBuilder("2"); 

ile sahaya oluşturulan ve atanan yeni bir örneğini başvurur. Bu değer statik başlatıcısı

private static StringBuilder sBuilder = new StringBuilder("1"); 

oluşturulan örneği başvuran ve Consumer olan birinde çalışacaktır. Yeni olanı yazarsın. formdur

ise şu şekildedir: Bir çağırma yönteminin Run-Time Evaluation of Method References

vücudu ilgilendiren Java Dil Şartnamede itibaren


, yöntem referans anlatım şeklinde bağlıdır ExpressionName :: [TypeArguments] Identifier veya Primary :: [TypeArguments] Identifier, daha sonra çağırma yönteminin gövdesi için bir yöntem çağırma ifadesinin etkisine sahiptir. ile-zaman beyanı, 'un derleme zamanı beyanı olan yöntem referans ifadesidir.

  • çağırma modu derleme zamanında elde edilir: yöntem çağırma ifadesinin çalışma zamanı değerlendirme §15.12.4.5, §15.12.4.4, §15.12.4.3 belirtilen ve olduğu gibi §15.12.3'te belirtilen beyanname. yöntem, referans sentezleme değerlendirilmiştir iken belirlenmiş olarak

  • hedef referans, ExpressionName veya Primary değeridir.

  • metot çağrımı ifade argümanlar çağırma yönteminin biçimsel parametrelerdir.

+1

cevap, 'ler -> sBuilder.append (ler)' 'eşdeğerdir s -> Main.sBuilder.append (ler)', 'iken sBuilder :: append', 'StringBuilder temp = Main.sBuilder; s - İstersen> temp.append (ler) ' –

+1

@TavianBarnes Bunu içinde düzenleyebilirsiniz. meraktan –

+0

, neden ilk başta topluluk wiki olarak işaretleyin? Jean-FrançoisSavard @ –