import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
public class LocalVarExample {
/**
* java8特性:lambda表达式语法
*/
public static void lambdaInJava8() {
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("before java8");
}
}).start();
new Thread(()-> System.out.println("in java8")).start();
List<String> list = Arrays.asList("java8","jdk8","1.8");
list.forEach(w->{
System.out.println("lambda in java8->"+w);
});
}
/**
*Java10 新特性:局部变量类型推断
*/
private static void varInJava10(){
int var =10;
var i =10;
var str = "java10";
var list = new ArrayList<String>();
var map = Map.of(1,"a",2,"b");
for(var entry : map.entrySet()){
System.out.println(entry);
}
}
/**
*Java11 新特性:允许var在声明隐式类型的lambda表达式的形式参数时使用
*/
private static void lambdaWithVarInJava11 (){
List<Integer> nums = Arrays.asList(9,11,23,3,7,2,8);
// nums.sort((s1,s2)->{
// if(s1.equals(s2)){
// return 0;
// }else{
// return s1 > s2 ? 1:-1;
// }
// });
nums.sort((@NotNull var s1, @NotNull var s2)->{
if (s1.equals(s2)) {
return 0;
} else {
return s1 > s2 ? 1 : -1;
}
});
nums.sort((s1,s2)-> s1 > s2 ? 1:-1);
System.out.println(nums);
}
/**
* Lambda参数的本地变量语法
*/
public static void main(String[] args) {
// lambdaInJava8();
// varInJava10();
lambdaWithVarInJava11();
}
}
jdk10允许使用var关键字来定义变量:var i=10(必须初始化,否则编译报错,一旦初始化完成过后类型就会确定,不能再赋予其他类型的值,即i不能赋值为“abc”或者2.0等非int类型的值)
http://openjdk.java.net/jeps/323
允许var在声明隐式类型的lambda表达式的形式参数时使用。
将隐式类型的lambda表达式中的形式参数声明的语法与局部变量声明的语法对齐。
将任何其他类型的变量声明(例如,方法的形式参数)的语法与局部变量声明的语法对齐。
一个lambda表达式可以被隐式类型,其中类型的所有形式参数都推断出:
(x, y) -> x.process(y) // implicitly typed lambda expression
Java SE 10使隐式类型可用于局部变量:
var x = new Foo();
for (var x : xs) { ... }
try (var x = ...) { ... } catch ...为了与局部变量保持一致,我们希望允许'var'用于隐式类型的lambda表达式的形式参数:
(var x, var y) -> x.process(y) // implicit typed lambda expression
统一性的一个好处是修饰符,特别是注释,可以应用于局部变量和lambda形式,而不会失去简洁性:
@Nonnull var x = new Foo(); (@Nonnull var x, @Nullable var y) -> x.process(y)
对于隐式类型的lambda表达式的形式参数,允许使用保留的类型名称var,以便:
(var x, var y) -> x.process(y)
相当于:
(x, y) -> x.process(y)
隐式类型的lambda表达式必须var用于其所有形式参数,或者不能用于任何形式参数。此外,var仅允许隐式类型化lambda表达式的形式参数---显式类型化的lambda表达式继续为其所有形式参数指定清单类型,因此某些形式参数不允许其他人使用清单类型var。以下示例是非法的:
(var x, y) -> x.process(y) // Cannot mix 'var' and 'no var' in implicitly typed lambda expression (var x, int y) -> x.process(y) // Cannot mix 'var' and manifest types in explicitly typed lambda expression
从理论上讲,有一个lambda表达式可能就像上面的最后一行一样,它是半显式类型(或半隐式类型,取决于你的观点)。但是,它超出了此JEP的范围,因为它会深刻影响类型推断和重载决策。这是保持lambda表达式必须指定所有清单参数类型或不指定的限制的主要原因。我们还希望强制推断隐式类型化lambda表达式的参数的类型是否相同无论是否var使用。我们可能会在未来的JEP中回到局部推断的问题。此外,我们不希望损害简写语法的简洁性,因此我们不允许使用以下表达式:
var x -> x.foo()