Einige Java 8-Funktionen werden offiziell von Android Studio 2.4 Preview 4 unterstützt Deshalb habe ich mich entschlossen, diese Gelegenheit zu nutzen, um die zusätzlichen Funktionen von Java 8 neu zu lernen. Ich habe Java8 noch nicht angesprochen, daher würde ich mich freuen, wenn Sie auf Fehler hinweisen könnten.
** 1. Android Studio aktualisieren ** Android Studio 2.4 Preview 4 Laden Sie das oben genannte herunter
** 2. Android Plug-In aktualisieren ** Öffnen Sie build.gradle unter dem Projekt und setzen Sie die Android-Plug-Version auf `` `2.4.0-alpha6``` oder höher.
buildscript {
dependencies {
classpath 'com.android.tools.build:gradle:2.4.0-alpha6'
}
}
** 3. Java-Version hinzufügen ** Fügen Sie build.gradle unter dem Modul Folgendes hinzu.
android {
...
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
Jetzt können Sie Java 8 verwenden.
Anonyme Klassenbeschreibungen können in einem vereinfachten Format für funktionale Schnittstellen implementiert werden. Allein anhand der Erklärung ist es schwer zu verstehen. Schauen Sie sich also zuerst den Code an.
Wenn Sie Java 8 oder früher schreiben, ohne Lambda-Ausdrücke zu verwenden, sieht der Code wie folgt aus.
public class Test {
public static void main(String args[]) {
Man man = new Man() {
@Override
public void laugh(String voice) {
System.out.println(voice);
}
};
man.laugh("Hahaha!");
}
interface Man {
void laugh(String voice);
}
}
Wenn Sie dies mit dem aus Java 8 eingeführten Lambda-Ausdruck umschreiben, sieht es folgendermaßen aus.
public class Test {
public static void main(String args[]) {
Man man = (voice) -> {System.out.println(voice);}
man.laugh("Hahaha!");
}
@FunctionalInterface
interface Man {
void laugh(String voice);
}
}
Sie sehen, dass der Implementierungsteil der Schnittstelle erheblich vereinfacht wurde.
Lambda-Ausdrücke können für funktionale Schnittstellen oder einfach für Schnittstellen verwendet werden, die nur eine abstrakte Methode haben.
Das Format des Lambda-Ausdrucks ist wie folgt.
(Argumente der zu implementierenden Methode) -> {wird bearbeitet}
Argumente der zu implementierenden Methode
Istvoice
Jedoch jede Zeichenfolge (x
Usw.), aber es gibt kein Problem.
Sie wundern sich vielleicht, dass vor dem Argument keine Typdeklaration steht. Da diese jedoch bei der Definition der abstrakten Methode festgelegt ist, ist der Typ nicht erforderlich (nach Typinferenz).
Wenn das Argument einfach ist, ist `()`
ebenfalls nicht erforderlich.
Wenn der Prozess eine Zeile umfasst, ist `{}`
nicht erforderlich.
Basierend auf dem Obigen kann es wie folgt weiter vereinfacht werden.
Man man = voice -> System.out.println(voice);
Haben Sie auch bemerkt, dass vor der `Man``` -Schnittstelle die`
@ FunctionalInterface Annotation steht? Diese Annotation wurde auch mit dem Lambda-Ausdruck eingeführt, um anzuzeigen, dass es sich um eine funktionale Schnittstelle handelt. Wenn Sie eine andere abstrakte Methode für die Schnittstelle definieren, in der `` @ FunctionalInterface
definiert ist, tritt ein Kompilierungsfehler auf.
Angenommen, Sie haben der Schnittstelle, die zuvor in Lambda-Ausdrücken geschrieben wurde, eine weitere abstrakte Methode hinzugefügt.
In diesem Fall können Sie keine Lambda-Ausdrücke schreiben, daher müssen Sie den Code in einer neuen anonymen Klasse neu schreiben.
Durch Hinzufügen von `` `@ FunctionalInterface```, um dies zu verhindern, hat es die Aufgabe, den Implementierer im Voraus zu benachrichtigen.
Wie Sie an der Tatsache sehen können, dass anonyme Klassen mit Lambda-Ausdrücken umgeschrieben werden können, erben Lambda-Ausdrücke die Spezifikationen anonymer Klassen. Anonyme Klassen konnten nicht auf lokale Variablen zugreifen, die nicht mit `` `final``` deklariert wurden, Lambda-Ausdrücke jedoch auch nicht. ***Jedoch! *** *** Ab Java8 wird der Wert zum Zeitpunkt der Deklaration der lokalen Variablen eingeführt. Wenn er seitdem nicht geändert wurde, wird er als "final" angesehen, und es gibt kein Problem, auch wenn Sie "final" nicht hinzufügen.
public static void main(String args[]) {
String name = "hoge";
Man man = new Man() {
@Override
public void laugh(String voice) {
System.out.print(voice);
System.out.print(name); //Kein Kompilierungsfehler
}
};
// name = "bar"; //Das Kommentieren führt zu einem Kompilierungsfehler.
}
Es gibt einen Unterschied in der Referenzierung von `this``` zwischen anonymen Klassen und Lambda-Ausdrücken. Wenn Sie
this``` in einer anonymen Klasse verwenden, bezieht sich dies auf die anonyme Klasse selbst. Wenn Sie jedoch ``
this``` in einem Lambda-Ausdruck verwenden, verweist es auf die implementierte Klasse.
Man man = new Man() {
@Override
public void laugh(String voice) {
System.out.println(this.getClass()); // class xxx.yyy.zzz.Test$1
}
};
Man man2 = voice -> System.out.println(this.getClass()); // class xxx.yyy.zzz.Test
Mit Methodenreferenzen können Sie vereinfachte Lambda-Ausdrücke schreiben. Bei Verwendung einer solchen Schnittstelle
interface Man {
void laugh(String voice);
}
Obwohl es in der Lambda-Formel so beschrieben wurde,
Man man = voice -> System.out.print(voice);
Die Methodenreferenz sieht so aus.
Man man = System.out::print;
Sie können sehen, dass das Argument verschwindet und die Methodenkette `::`
enthält.
Das Format der Methodenreferenz ist wie folgt.
Name der Klasse::Methodenname
Im Fall einer Instanzmethode ist dies wie folgt.
```java
Test test = new Test();
Man man = test::method;
Eine Methodenreferenz kann verwendet werden, wenn das Argument der abstrakten Methode und das an den Prozess übergebene Argument identisch sind, dh wenn die Signatur der abstrakten Methode und die zu verarbeitende Methode identisch sind.
system$out#print(string s)
Wannman#laugh(string voice)
Beidestring
Typ ArgumentEiner
であるこWannからメソッド参照が可能なわけです。
Nehmen wir zwei Argumente.
interface Man {
void laugh(String voice, String voice2);
}
textutils#split(string text, string expression)
Ist zweistring
Da es einen Typ als Argument hat, kann es durch eine Methodenreferenz wie diese beschrieben werden.
Man man = TextUtils::split;
Durch die Verwendung von Methodenreferenzen wird Ihr Code sauberer, aber weniger lesbar. Halten Sie ihn daher am besten auf Lambda.
Es gibt seit einiger Zeit Typanmerkungen, aber Java 8 hat neue `TYPE_PARAMETER``` und`
TYPE_USE hinzugefügt. *** `` `TYPE_PARAMETER
und` `` TYPE_USE``` sind ab API-Level 24 verfügbar. *** ***
Typanmerkungen werden verwendet, um zu deklarieren, wo Annotationen definiert werden können. Zum Beispiel ist im Fall von "@ Override" wie folgt definiert.
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}
Die Typanmerkung lautet @ Target (ElementType.METHOD)
, und
ElementType.METHOD`
gibt an, dass diese Anmerkung in der Methode deklariert werden kann.
Beschreibt den neuen `TYPE_PARAMETER``` und`
TYPE_USE```, die aus Java 8 hinzugefügt wurden.
type_parameter
Kann für generische Parameter verwendet werden.
@Target(ElementType.TYPE_PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface TestParam {}
public class Test<@TestParam E>{
public <@TestParam F> F method(){
//...
}
}
type_use
Kann überall dort verwendet werden, wo der Typ deklariert ist.
@Target(ElementType.TYPE_USE)
public @interface TestType {}
Ich werde nicht alle Beispiele aufschreiben, aber im Moment kann es überall dort verwendet werden, wo es eine Typdeklaration gibt.
@TestType //Typdeklaration
public class MyApp<@TestType T> //Geben Sie die Parameterdeklaration ein
extends @TestType Application{ //Typ zum Erweitern (oder Implementieren)
@Override
public void start(@TestType Stage stage) { //Parametertyp
}
*** Verfügbar ab API-Level 24. Es scheint jedoch, dass Instant Run derzeit nicht unterstützt wird. (Ausgabe Nr. 302460) ***
In Java8 können Sie statische Methoden in der Schnittstelle definieren.
interface Man {
static void staticMethod(){
System.out.print("static method");
}
}
Das Aufrufen einer statischen Methode entspricht dem normalen Aufrufen einer statischen Methode.
Man.staticMethod();
Default
Früher konnten Schnittstellen nur abstrakte Methoden definieren, jetzt können Sie auch Implementierungsmethoden definieren. Um eine Implementierungsmethode zu definieren, stellen Sie der Methode `` `default``` voran.
interface Man {
void laugh();
default void sayGreeting() {
System.out.println("Hello");
}
}
Wenn Sie die obige Schnittstelle implementieren, müssen Sie nur mindestens die `lachen ()`
Methode implementieren.
public class Test {
public static void main(String args[]) {
Man man = new Man() {
@Override
public void laugh() {
System.out.println("Hahaha!");
}
};
man.laugh(); // "Hahaha!"
man.sayGreeting(); // "Hello"
}
interface Man {
void laugh();
default void sayGreeting() {
System.out.println("Hello");
}
}
}
Natürlich können Sie auch die Verarbeitung von `sayGreeting ()` `ändern, indem Sie` `sayGreeting ()` `überschreiben. Als Gefühl ist es in der Klasse "abstrakt". Mehrfachvererbung ist in Java nicht zulässig, Mehrfachvererbung ist jedoch nur für Schnittstellen möglich. Daher ist die
abstract``` Klasse, die mehrere Schnittstellen erbt, jetzt
erweitert```, aber nur
`implementiertist erforderlich. Ich bin mir auch sicher, dass es einige Methoden gibt, die Sie bei der Implementierung der Rückrufschnittstelle nicht verwenden. Bis jetzt musste ich all diese Methoden überschreiben,
default```Sie können jetzt vermeiden, nutzlose Methoden zu überschreiben, indem Sie verwenden.
Die Methodenreferenz ergab auf den ersten Blick keinen Sinn. Selbst wenn ich es verstehe, bin ich nicht daran gewöhnt, also bin ich verwirrt. Ich wollte nicht, dass du es benutzt, wenn es möglich ist.
das ist alles.
Recommended Posts