Réintroduction de Java8, disponible depuis Android Studio 2.4

Certaines fonctionnalités de Java 8 sont officiellement prises en charge à partir d'Android Studio 2.4 Preview 4 J'ai donc décidé de profiter de cette opportunité pour réapprendre les fonctionnalités supplémentaires de Java 8. Je n'ai pas abordé Java8, alors je vous serais reconnaissant si vous pouviez signaler des erreurs.

Pour utiliser Java 8 avec Android Studio

Je me réfère au document ici.

** 1. Mettez à jour Android Studio ** Android Studio 2.4 Preview 4 Téléchargez ce qui précède

** 2. Mettez à jour le plug-in Android ** Ouvrez build.gradle sous le projet et définissez la version de la prise Android sur `` 2.4.0-alpha6 '' ou plus.

buildscript {
    dependencies {
        classpath 'com.android.tools.build:gradle:2.4.0-alpha6'
    }
}

** 3. Ajouter la version Java ** Ajoutez ce qui suit à build.gradle sous le module.

android {
  ...
  compileOptions {
    sourceCompatibility JavaVersion.VERSION_1_8
    targetCompatibility JavaVersion.VERSION_1_8
    }
}

Vous pouvez maintenant utiliser Java 8.

Expressions Lambda

Vous pouvez implémenter une description de classe anonyme dans un format simplifié pour les interfaces fonctionnelles. C'est difficile à comprendre à partir de l'explication seule, alors jetez d'abord un coup d'œil au code.

Si vous écrivez Java 8 ou une version antérieure sans utiliser d'expressions lambda, le code ressemblera à ce qui suit.

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);
    }
}

Si vous réécrivez ceci en utilisant l'expression lambda introduite à partir de Java 8, cela ressemblera à ceci.

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);
    }
}

Vous pouvez voir que la partie implémentation de l'interface a été considérablement simplifiée. Les expressions Lambda peuvent être utilisées pour des interfaces fonctionnelles, ou simplement pour des interfaces qui n'ont qu'une seule méthode abstraite. Le format de l'expression lambda est le suivant. (Arguments de la méthode à implémenter) -> {En traitement}

Arguments de la méthode à implémenterEstvoiceMais toute chaîne de caractères (xEtc.), mais il n'y a pas de problème. Vous vous demandez peut-être qu'il n'y a pas de déclaration de type avant l'argument, mais comme elle est corrigée lorsque la méthode abstraite est définie, le type est inutile (par inférence de type). Si l'argument est unique, () '' est également inutile. Si le processus est une ligne, {} '' n'est pas nécessaire. Sur la base de ce qui précède, il peut être encore simplifié comme suit.

Man man = voice -> System.out.println(voice);

De plus, avez-vous remarqué que l'interface Man '' est précédée de l'annotation @ FunctionalInterface ''? Cette annotation a également été introduite avec l'expression lambda pour indiquer qu'il s'agit d'une interface fonctionnelle. Si vous définissez une autre méthode abstraite pour l'interface où @ FunctionalInterface``` est défini, une erreur de compilation se produira. Supposons que vous ayez ajouté une autre méthode abstraite à l'interface qui était précédemment écrite dans des expressions lambda. Dans ce cas, vous ne pourrez pas écrire d'expressions lambda, vous devrez donc réécrire le code avec une nouvelle classe anonyme. En ajoutant `` @ FunctionalInterface '' pour éviter que cela ne se produise, il a pour rôle de notifier à l'avance l'implémenteur.

Comme vous pouvez le voir du fait que les classes anonymes peuvent être réécrites avec des expressions lambda, les expressions lambda héritent des spécifications des classes anonymes. Les classes anonymes ne pouvaient pas accéder aux variables locales qui n'ont pas été déclarées avec final```, mais les expressions lambda ne le font pas non plus. ***Pourtant! *** *** A partir de Java8, la valeur est introduite au moment de la déclaration de la variable locale, et si elle n'a pas été modifiée depuis, elle est considérée comme finale '', et il n'y a pas de problème même si vous n'ajoutez pas final ''.

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); //Aucune erreur de compilation
        }
    };
    // name = "bar";  //La décommentation entraînera une erreur de compilation.
}

Il existe une différence dans le référencement de this entre les classes anonymes et les expressions lambda. Si vous utilisez `` this dans une classe anonyme, cela fait référence à la classe anonyme elle-même. Cependant, si vous utilisez `` this``` dans une expression lambda, cela fera référence à la classe implémentée.

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

Références de méthode (https://docs.oracle.com/javase/tutorial/java/javaOO/methodreferences.html)

Les références de méthode vous permettent d'écrire des expressions lambda plus simplifiées. Lors de l'utilisation d'une telle interface

interface Man {
    void laugh(String voice);
}

Dans la formule lambda, il a été décrit comme ceci,

Man man = voice -> System.out.print(voice);

La référence de méthode ressemble à ceci.

Man man = System.out::print;

Vous pouvez voir que l'argument disparaît et que la chaîne de méthodes contient :: '' ``. Le format de la référence de méthode est le suivant.

nom de la classe::Nom de la méthode


  
 Dans le cas d'une méthode d'instance, ce sera comme suit.

```java
Test test = new Test();
Man man = test::method;

Une référence de méthode peut être utilisée lorsque l'argument de la méthode abstraite et l'argument passé au processus sont les mêmes, c'est-à-dire lorsque la signature de la méthode abstraite et la méthode à traiter sont identiques. system$out#print(string s)Quandman#laugh(string voice)Tous les deuxstringArgument de typeUnであるこQuandからメソッド参照が可能なわけです。

Prenons deux arguments.

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

textutils#split(string text, string expression)Est deuxstringPuisqu'il a un type comme argument, il peut être décrit par une référence de méthode comme celle-ci.

Man man = TextUtils::split;

L'utilisation de références de méthode rendra votre code plus propre, mais il est moins lisible, il est donc préférable de le garder lambda.

Tapez une annotation

Il y a eu des annotations de type depuis un certain temps, mais Java 8 a ajouté de nouveaux TYPE_PARAMETER``` et TYPE_USE```. *** TYPE_PARAMETER '' et TYPE_USE '' sont disponibles au niveau de l'API 24 et supérieur. *** ***

Les annotations de type sont utilisées pour déclarer où les annotations peuvent être définies. Par exemple, dans le cas de `` @ Override '', il est défini comme suit.

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}

L'annotation de type est `@ Target (ElementType.METHOD)`, et ElementType.METHOD indique que cette annotation peut être déclarée dans la méthode. Décrit les nouveaux TYPE_PARAMETER '' et TYPE_USE '' ajoutés à partir de Java 8.

type_parameterPeut être utilisé pour les paramètres génériques.

@Target(ElementType.TYPE_PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface TestParam {}
public class Test<@TestParam E>{

    public <@TestParam F> F method(){
        //...
    }
}

type_usePeut être utilisé partout où le type est déclaré.

@Target(ElementType.TYPE_USE)
public @interface TestType {}

Je n'écrirai pas tous les exemples, mais pour l'instant, il peut être utilisé partout où il y a une déclaration de type.

@TestType    //Déclaration de type
public class MyApp<@TestType T>    //Déclaration de paramètre de type
        extends @TestType Application{    //Tapez pour étendre (ou mettre en œuvre)

    @Override
    public void start(@TestType Stage stage) {    //Type de paramètre
    }

Ajoutez des méthodes par défaut et statiques à l'interface (https://docs.oracle.com/javase/8/docs/api/java/lang/reflect/Method.html#isDefault--)

*** Disponible au niveau API 24 et supérieur. Cependant, il semble qu'il ne prend pas en charge Instant Run à ce stade. (Problème n ° 302460) ***

méthode statique

Depuis java8, vous pouvez définir des méthodes statiques dans l'interface.

interface Man {
    static void staticMethod(){
        System.out.print("static method");
    }
}

L'appel d'une méthode statique revient à appeler normalement une méthode statique.

Man.staticMethod();

Default

Auparavant, les interfaces ne pouvaient définir que des méthodes abstraites, mais maintenant vous pouvez également définir des méthodes d'implémentation. Pour définir une méthode d'implémentation, préfixez la méthode avec `` par défaut ''.

interface Man {
    void laugh();

    default void sayGreeting() {
        System.out.println("Hello");
    }
}

Lors de l'implémentation de l'interface ci-dessus, il vous suffit d'implémenter au moins la méthode `` rire () ''.

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");
        }
    }
}

Bien sûr, vous pouvez également modifier le traitement de sayGreeting () '' en remplaçant sayGreeting () ''. En tant que sentiment, il est dans la classe abstract. L'héritage multiple n'est pas autorisé en Java, mais l'héritage multiple n'est possible que pour les interfaces. Par conséquent, la classe abstract qui hérite de plusieurs interfaces est maintenant implements au lieu de extends. En outre, je suis sûr qu'il existe certaines méthodes que vous n'utilisez pas lors de la mise en œuvre de l'interface de rappel. Jusqu'à présent, je devais remplacer toutes ces méthodes, defaultVous pouvez maintenant éviter de remplacer les méthodes inutiles en utilisant.

en conclusion

La référence à la méthode n'avait aucun sens à première vue. Même si je le comprends, je n'y suis pas habitué, donc je suis confus. Je ne voulais pas que vous l'utilisiez si possible.

c'est tout.

Recommended Posts

Réintroduction de Java8, disponible depuis Android Studio 2.4
Exécutez node.js depuis Android Java (traitement)
[Android Studio] [Java] Mémos et liens d'apprentissage
Appeler java depuis C ++ sur Android NDK
[Android Studio] Transition d'écran par le bouton [Java]
De Java à C et de C à Java dans Android Studio
[Android] Appeler la méthode d'argument par défaut de Kotlin depuis Java
Appeler Java depuis JRuby
[Android Studio] Comment changer TextView en n'importe quelle police [Java]
Changements de Java 8 à Java 11
Somme de Java_1 à 100
Évaluer la source Java à partir de Java
[Android Studio] [Java] Comment réparer l'écran verticalement
Accédez à API.AI depuis Java
De Java à Ruby !!
Remarques sur le studio Android
Vaincre Android Studio Partie 3-6
Vaincre Android Studio Partie 1 et Partie 2
Java qui ignore les données d'Android vers le ROS de Jetson Nano
Reportez-vous à C ++ dans le module Android Studio (Java / kotlin)
Utilisez Java inclus avec Android Studio pour créer React Native
Utiliser un JDK d'un autre fournisseur OpenJDK dans Android Studio
Vous utilisez actuellement Java 6. Solution dans Android Studio Gradle
Migration de Cobol vers JAVA
Java à partir du débutant, remplacer
Création d'index Elastic Search à partir de Java
Java, instance à partir du débutant
Java avec Visual Studio Code
Java à partir de débutant, héritage
La vie Java à partir de zéro
[Java] [Android] Lire le fichier ini
Utilisation de Docker depuis Java Gradle
De Java inefficace à Java efficace
JavaScript vu de Java
[Android / Java] En savoir plus sur DataBinding
Exécuter des instructions non-Java à partir de Java
Android: Comment gérer "Impossible de déterminer la version Java à partir de '10 .0.1 '"
[Android, Java] Méthode pour trouver la date écoulée à partir de deux dates
Ce que j'ai appris en travaillant Java avec Visual Studio Code
Déterminer si un clavier personnalisé est activé dans Android Studio (Java)