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.
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.
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 implement
Isvoice
However, any character string (x
Etc.), 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 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)
Bothstring
Type argumentOne
であるこWhenからメソッド参照が可能なわけです。
Let's take two arguments.
interface Man {
void laugh(String voice, String voice2);
}
textutils#split(string text, string expression)
Is twostring
Since 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.
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_parameter
Can 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_use
Can 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
}
*** Available at API level 24 and above. However, it seems that it does not support Instant Run at this stage. (Issue # 302460) ***
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,
default
You can now avoid overriding useless methods by using.
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