Reintroducing Java 8 available from Android Studio 2.4

Some Java 8 features officially supported from Android Studio 2.4 Preview 4 So I decided to take this opportunity to relearn about the additional features of Java 8. I haven't touched on Java8, so I'd appreciate it if you could point out any mistakes.

To use Java 8 with Android Studio

I refer to the document of here.

** 1. Update Android Studio ** Android Studio 2.4 Preview 4 Download the above

** 2. Update Android plugin ** Open build.gradle under the project and set the Android plugin version to `` `2.4.0-alpha6``` or higher.

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

** 3. Java version added ** Please add the following to build.gradle under the module.

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

Now you can use Java 8.

Lambda expressions

Anonymous class descriptions can be implemented in a simplified format for functional interfaces. It's hard to understand from the explanation alone, so please take a look at the code first.

If you write Java 8 or earlier without using lambda expressions, the code will be as follows.

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

Rewriting this using a lambda expression introduced in Java 8 looks like this:

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

You can see that the implementation part of the interface has been considerably simplified. Lambda expressions can be used for functional interfaces, or simply for interfaces that have only one abstract method. The format of the lambda expression is as follows. (Arguments of the method to implement) -> {processing}

Arguments of the method to implementIsvoiceHowever, any character string (xEtc.), but there is no problem. You may be wondering that there is no type declaration before the argument, but since it is fixed when the abstract method is defined, the type is no longer needed (by type inference). With a single argument, `() ``` is also unnecessary. If the process is one line, ``` {}` is unnecessary. Based on the above, it can be further simplified as follows.

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

Also, did you notice that the `Man interface is preceded by the `@ FunctionalInterface``` annotation? This annotation was also introduced with the lambda expression to indicate that it is a functional interface. If you define another abstract method on the interface where ``` @ FunctionalInterface``` is defined, a compile error will occur. Suppose you add another abstract method to the interface that you used to write in a lambda expression. In that case, you will not be able to write lambda expressions, so you will need to rewrite the code with a new anonymous class. By adding `@ FunctionalInterface``` to prevent this from happening, it has the role of notifying the implementer in advance.

As you can see from the fact that anonymous classes can be rewritten with lambda expressions, lambda expressions inherit the specifications of anonymous classes. Anonymous classes couldn't access local variables that weren't declared with final, but lambda expressions also don't. ***However! *** *** From Java8, the value is introduced at the time of local variable declaration, and if it has not been changed since then, it is regarded as `final```, and there is no problem even if you do not add `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); //No compilation error
        }
    };
    // name = "bar";  //If you uncomment, you will get a compile error.
}

There is a difference in the reference of `this``` between anonymous classes and lambda expressions. If you use ``` this``` in an anonymous class, it refers to the anonymous class itself. However, if you use `this``` in a lambda expression, it will refer to the implemented class.

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

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

Method references allow you to write a more simplified description of your lambda expression. When using such an interface,

interface Man {
    void laugh(String voice);
}

Although it was described like this in the lambda expression,

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

The method reference looks like this.

Man man = System.out::print;

You can see that the argument disappears and the method chain contains `::`. The format of the method reference is as follows.

name of the class::Method name


  
 In the case of instance method, it will be as follows.

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

A method reference can be used when the argument of the abstract method and the argument passed to the process are the same, that is, when the signature of the abstract method and the method to be processed are the same. system$out#print(string s)Whenman#laugh(string voice)BothstringType argumentOneであるこWhenからメソッド参照が可能なわけです。

Let's take two arguments.

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

textutils#split(string text, string expression)Is twostringSince it has a type as an argument, it can be described by a method reference like this.

Man man = TextUtils::split;

Using method references can make your code cleaner, but it's less readable, so it's a good idea to keep it lambda.

Type Annotation

There are type annotations from before, but Java 8 has added new `TYPE_PARAMETER``` and TYPE_USE```. *** `` TYPE_PARAMETERand TYPE_USE``` are available at API level 24 and above. *** ***

Type annotations are used to declare where annotations can be defined. For example, in the case of @ Override, it is defined as follows.

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

The type annotation is `@ Target (ElementType.METHOD)`, and ElementType.METHOD indicates that this annotation can be declared in the method. Describes the new TYPE_PARAMETER and `` `TYPE_USE``` added from Java 8.

type_parameterCan be used for generics parameters.

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

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

type_useCan be used wherever the type is declared.

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

I won't write out all the examples, but for now it can be used wherever there is a type declaration.

@TestType    //Type declaration
public class MyApp<@TestType T>    //Type parameter declaration
        extends @TestType Application{    //Type to extend (or implement)

    @Override
    public void start(@TestType Stage stage) {    //Parameter type
    }

Add Default and static methods to interface (https://docs.oracle.com/javase/8/docs/api/java/lang/reflect/Method.html#isDefault--)

*** Available at API level 24 and above. However, it seems that it does not support Instant Run at this stage. (Issue # 302460) ***

static method

From java8, you can define static methods in the interface.

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

Calling a static method is the same as calling a static method normally.

Man.staticMethod();

Default

Previously, interfaces could only define abstract methods, but now you can also define implementation methods. To define an implementation method, prefix the method with default.

interface Man {
    void laugh();

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

When implementing the above interface, you only need to implement at least the `laugh ()` method.

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

Of course, you can also change the processing of `sayGreeting ()` by overriding `` sayGreeting () `. As a feeling, it's in the abstract class. Multiple inheritance is not allowed in Java, but multiple inheritance is possible only for interfaces. So, instead of extends of the abstract class that inherited multiple interfaces, you can now just do implements. Also, I'm sure there are some methods that you don't use when implementing the callback interface. Until now, I had to override all those methods, defaultYou can now avoid overriding useless methods by using.

in conclusion

The method reference didn't make any sense at first glance. Even if I understand it, I'm not used to it, so I'm confused. I didn't want you to use it if possible.

that's all.

Recommended Posts

Reintroducing Java 8 available from Android Studio 2.4
Run node.js from android java (processing)
[Android Studio] [Java] Learning memos & links
Calling java from C ++ on Android NDK
Screen transition by [Android Studio] [Java] button
Java to C and C to Java in Android Studio
[Android] Call Kotlin's default argument method from Java
Call Java from JRuby
[Android Studio] How to change TextView to any font [Java]
Changes from Java 8 to Java 11
Sum from Java_1 to 100
Eval Java source from Java
[Android Studio] [Java] How to fix the screen vertically
Access API.AI from Java
From Java to Ruby !!
Notes in Android studio
Defeating Android Studio Part 3-6
Defeating Android Studio Part 1 & Part 2
Java to fly data from Android to ROS of Jetson Nano
Refer to C ++ in the Android Studio module (Java / kotlin)
Use Java included with Android Studio to build React Native
Use a JDK from another OpenJDK provider in Android Studio
You are currently using Java 6. Solution in Android Studio Gradle
Migration from Cobol to JAVA
Java starting from beginner, override
Creating ElasticSearch index from Java
Java, instance starting from beginner
Java in Visual Studio Code
Java starting from beginner, inheritance
Java life starting from scratch
[Java] [Android] Read ini file
Using Docker from Java Gradle
From Ineffective Java to Effective Java
JavaScript as seen from Java
[Android / Java] Learned about DataBinding
Execute non-Java instructions from Java
Android: How to deal with "Could not determine java version from '10 .0.1'"
[Android, Java] Method to find the elapsed date from two dates
What I learned from doing Java work with Visual Studio Code
Determining if a custom keyboard is enabled in Android Studio (Java)