Wiedereinführung von Java8, das seit Android Studio 2.4 verfügbar ist

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.

So verwenden Sie Java 8 mit Android Studio

** 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.

Lambda-Ausdrücke

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 MethodeIstvoiceJedoch jede Zeichenfolge (xUsw.), 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

Methodenreferenzen (https://docs.oracle.com/javase/tutorial/java/javaOO/methodreferences.html)

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)BeidestringTyp ArgumentEinerであるこWannからメソッド参照が可能なわけです。

Nehmen wir zwei Argumente.

interface Man {
    void laugh(String voice, String voice2);
}

textutils#split(string text, string expression)Ist zweistringDa 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.

Typanmerkung

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_parameterKann 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_useKann ü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
    }

Hinzufügen von Standard- und statischen Methoden zur Schnittstelle (https://docs.oracle.com/javase/8/docs/api/java/lang/reflect/Method.html#isDefault--)

*** Verfügbar ab API-Level 24. Es scheint jedoch, dass Instant Run derzeit nicht unterstützt wird. (Ausgabe Nr. 302460) ***

statische Methode

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.

abschließend

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

Wiedereinführung von Java8, das seit Android Studio 2.4 verfügbar ist
Führen Sie node.js von Android Java aus (Verarbeitung)
[Android Studio] [Java] Memos und Links lernen
Rufen Sie Java von C ++ auf Android NDK auf
[Android Studio] Bildschirmübergang über die Schaltfläche [Java]
Von Java nach C und von C nach Java in Android Studio
[Android] Rufen Sie Kotlins Standardargumentmethode von Java aus auf
Rufen Sie Java von JRuby aus auf
[Android Studio] So ändern Sie TextView in eine beliebige Schriftart [Java]
Änderungen von Java 8 zu Java 11
Summe von Java_1 bis 100
Eval Java-Quelle von Java
[Android Studio] [Java] So fixieren Sie den Bildschirm vertikal
Greifen Sie über Java auf API.AI zu
Von Java zu Ruby !!
Hinweise zu Android Studio
Android Studio Teil 3-6 besiegen
Android Studio Teil 1 und Teil 2 besiegen
Java, das Daten von Android zu Jetson Nanos ROS überspringt
Siehe C ++ im Android Studio-Modul (Java / Kotlin)
Verwenden Sie Java, das in Android Studio enthalten ist, um React Native zu erstellen
Verwenden Sie ein JDK eines anderen OpenJDK-Anbieters in Android Studio
Sie verwenden derzeit Java 6. Lösung in Android Studio Gradle
Migration von Cobol nach JAVA
Java ab Anfänger überschreiben
Elastic Search Indexerstellung aus Java
Java, Instanz für Anfänger
Java mit Visual Studio Code
Java ab Anfänger, Vererbung
Java-Leben von vorne anfangen
[Java] [Android] INI-Datei lesen
Verwenden von Docker von Java Gradle
Von ineffektivem Java zu effektivem Java
JavaScript von Java aus gesehen
[Android / Java] Erfahren Sie mehr über DataBinding
Führen Sie Nicht-Java-Anweisungen von Java aus
Android: Umgang mit "Java-Version von '10 .0.1 'konnte nicht ermittelt werden"
[Android, Java] Methode zum Ermitteln des abgelaufenen Datums aus zwei Daten
Was ich aus Java gelernt habe, funktioniert mit Visual Studio Code
Feststellen, ob eine benutzerdefinierte Tastatur in Android Studio (Java) aktiviert ist