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.
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.
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émenter
Estvoice
Mais toute chaîne de caractères (x
Etc.), 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
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 deuxstring
Argument de typeUn
であるこQuandからメソッド参照が可能なわけです。
Prenons deux arguments.
interface Man {
void laugh(String voice, String voice2);
}
textutils#split(string text, string expression)
Est deuxstring
Puisqu'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.
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_parameter
Peut ê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_use
Peut ê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
}
*** 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) ***
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,
default
Vous pouvez maintenant éviter de remplacer les méthodes inutiles en utilisant.
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