2016-03-28 10 views
-3

Für diejenigen, die jemals in C, C++ oder ObjectiveC geschrieben haben, verstehen Sie Blöcke ist sehr einfach. Warum ist es so schwierig, das Konzept in Java (8) zu bekommen?Java-Blöcke, Closures, Lambdas ... einfach erklärt

Ich werde meine Frage beantworten!

+0

deklariert wird Dies ist keine echte Frage - es fragt nicht nach einem bestimmten Problem. –

+2

Es ist auch zu breit, und die Antwort ist an mehreren Stellen ungenau. – chrylis

+0

Java basiert auf C und C++, also ist das Verhalten von '{}' sehr ähnlich. Es ist nicht klar, was dein Zweifel ist. –

Antwort

-2

Alles, was Sie verstehen müssen, ist "Typ".

Eine Variable hat einen Typ. Beispiel:

int i, double d… 

Ein Objekt hat einen Typ (A-Klasse). ZB:

String s, Number n, Object o, MyClass m… 

Eine Funktion hat einen Typ. ZB:

void function() <= this type is: a function with no return and no param. 
void function (type param) <= this type is: a function with no return with a param of type ‘type’ 
type function (type param) <= this type is: a function with a return of type ‘type’ and a param of type ‘type’ 

Was ist ein Block/Schließung/Lambda?

Es ist im Grunde eine lokale Funktion eines bestimmten Typs, die an eine andere Funktion als Parameter übergeben wird.

So haben wir gehört: eine Funktion, die eine Funktion eines bestimmten Typs als Parameter übernimmt. Und die Funktion, die die Funktion empfängt und startet es!

Die Hauptanwendung ist: CallBack und Comparaison Funktionen. Aber der Traum ist offen.

Wir können machen, dass als:

type function(type function_param) { 
    excute the function_param 
} 

Wie dies in Java sagen.

1/erklären die Art des Blocks/Schließ/lambda

2/erstellen, die Funktion (in einer Klasse oder nicht), die diese Art von Typ wie param

3/erstellen, um die lokale Funktion erhalten vom Typ des Blocks/Schließung/Lambda

4/übergeben Sie es als Parameter für die Funktion, die es verwenden.

Eg:

// 1 declaring the type of block/closure/lambda 
interface CallBack { 
    public int function(String string); 
} 

class MyClass { 
    private String name; 
    MyClass(String name) { this.name = name; } 
    void display() { System.out.println(this.name); } 

    // 2 creating the function that which that kind of type as param 
    int myFunction(CallBack funcCallBack) { 
     return funcCallBack.function(name); 
    } 
} 


public class Main { 

    public static void main(String[] args) { 

     // 3 Create the local function of the type of the block/closure/lambda 
     CallBack message = (String string) -> { 
      System.out.println("Message: "+string); 
      return 1; 
     }; 

     MyClass mc = new MyClass("MyClass"); 
     mc.display(); 

     // 4 pass it as param to the function which use it. 
     int res = mc.myFunction(message); 
     System.out.println(res); 

    } 
} 

Ausgang

MyClass

Nachricht: MyClass

2

Blocken

Nur eine Liste von Anweisungen, die von geschweiften Klammern umgeben sind. Das ist alles. Ein Block wird ausgeführt, indem seine einzelnen Anweisungen nacheinander ausgeführt werden. Es ist nichts wie ein "Block" in der Programmiersprache Ruby.

Closure

Java keine Schließungen haben, aber es hat etwas, das so aussieht:

int limit = ...; 

Thread t = new Thread(new Runnable() { 
    @Override 
    public void run() { 
     for (int i=0 ; i<limit ; i++) { ... } 
    } 
}); 

Das wie die Methode run() aussehen kann, bezieht sich auf die Variable limit in Der äußere Bereich wird jedoch nicht kompiliert, es sei denn, die Variable limit ist tatsächlich unveränderbar. Was wirklich passiert ist, dass die anonyme innere Klasse hat eine Membervariablelimit genannt, und einen versteckten Konstruktor, der ein Argumentlimit genannt, und der Wert wird durch Kopieren der Wert von limit von dem an den Konstruktor geliefert Umgebungsumfang.

Lambda

Mehr Rauch und Spiegel. Der Wert eines Lambda-Ausdrucks in Java ist keine Funktion: Es ist eine Instanz einer anonymen inneren Klasse, die eine Funktionsschnittstelle implementiert. Der gleiche Code, die ich oben schrieb könnte prägnanter als Java-Lambda-Ausdruck geschrieben werden:

int limit = ...; 
Thread t = new Thread(() -> { 
    for (int i=0 ; i<limit ; i++) { ... } 
}); 

Java8 führt die Idee eines @Functional Interface-Typs, die genau eine Methode deklarieren müssen. In diesem Fall haben sie die java.lang.Runnable Klasse @Functional seinen

retconned

Wenn der Compiler den Code oben liest, es kennt die anonyme Klasse implementieren die Runnable Schnittstelle zu machen, denn das ist die einzige Art ist, die von dem Thread Konstruktor akzeptiert wird, und es weiß, dass der Körper des Lambda die run() Methode werden sollte, weil das die einzige Methode ist, die von Runnable.

+0

Danke James für deinen Beitrag. Ich habe nicht über diese Art von Blöcken gesprochen, aber Blöcke wie Apple fügte sie in C, C++ und Objective-C (https://en.wikipedia.org/wiki/Blocks_%28C_language_extension%29), die Closures oder Lambdas bedeutet. Also, was Sie erklären, ist nicht die Art von "Blöcken" Funktionalitäten, über die ich sprach. Ich vermisste es, meine Gedanken richtig zu erklären. –