本文列举了从Java8到11各个变化的API:
变量
从Java 10开始,开发人员可以选择让编译器使用var来推断类型:
var x=1.0/2.0
var list = new ArrayList<String>();
var stream = list.stream();
// Type inference can be (Java 8) Function helloFunction = s -> "Hello " + s; // Inference of generics (Diamond Operator, since Java 7) List strings = new ArrayList<>(); strings.add(helloFunction.apply("World")); // Inference of generics (Diamond Operator) with anonymous inner classes (Java 9 -> JEP 213) Consumer printer = new Consumer<>() { @Override public void accept(String string) { System.out.println(string); } }; strings.forEach(printer::accept);
|
Java11已经提高了lambda中的var能力:
IntFunction<Integer> doubleIt1 = (int x) -> x * 2; // OK Java 10 and 11 IntFunction<Integer> doubleIt2 = (var x) -> x * 2; // OK Java 11
|
更复杂案例:
/ /Inference of parameters in Lambda expressions Consumer<String> printer = (var s) -> System.out.println(s); // statt s -> System.out.println(s); // But no mixture of "var" and declarated types possible // BiConsumer<String, String> printer = (var s1, String s2) -> System.out.println(s1 + " " + s2); // Useful for type annotations BiConsumer<String, String> printer = (@Nonnull var s1, @Nullable var s2) -> System.out.println(s1 + (s2 == null ? "" : " " + s2));
// given Optional<String> value = Optional.of("properValue"); AtomicInteger successCounter = new AtomicInteger(0); AtomicInteger onEmptyOptionalCounter = new AtomicInteger(0); // when value.ifPresentOrElse( v -> successCounter.incrementAndGet(), onEmptyOptionalCounter::incrementAndGet);
|
String新方法
java 8加入新方法join:
Set<String> set1 = Set.of("a","b", "c"); List<String> list1 = List.of("a","b", "c"); System.out.println( String.join("a", "b", "c") ); System.out.println( String.join(".", set1) ); System.out.println( String.join(".", list1) );
|
Java9 有了一个返回Stream的新方法
Java11 添加了更多String的新方法:
String.repeat(int) String.lines() String.strip() String.stripLeading() String.stripTrailing() String.isBlank()
|
接口
java8:
- 常量Constant variables
- 抽象方法Abstract methods
- 默认方法Default methods
- 静态方法Static methods
Java9:
- Constant variables
- Abstract methods
- Default methods
- Static methods
- 私有方法Private methods
- 私有静态方法Private Static methods
Java11:
看一个接口的完整代码://generic interface with one type parameter T interface SomeInterface<T> { int SOME_CONSTANT = 35; // variable declaration int abstractMethod(int x, int y); // method declaration T abstractMethodUsingGenericType(T[] array, int i); // method using type parameter default int defaultMethod(int x, int y) { // implementation of method return 0; } static void main(String[] args) { // any static method, including main can be included in interface } private void privateMethod(String[] args) { // any private method can be included in interface } private static void staticMethod(String[] args) { // any private static method can be included in interface } // nested class definition class NestedClass { // members of a class } // nested interface definition interface NestedInterface { // member of an interface } // nested enum definition enum NestedEnum { OBJECT1, OBJECT2, ; // methods, variables and constructors } // nested annotation definition @interface NestedAnnotation { String attrib1(); } }
|
Nullable管理
java8引入了新的Optional。
// return an optional empty object Optional<String> optional = Optional.empty();
// return an optional with value object String str = "value"; Optional<String> optional = Optional.of(str);
// return an optional with or without value Optional<String> optional = Optional.ofNullable(getString()); // how to solve String version = computer?.getSoundcard()?.getUSB()?.getVersion() ?: "UNKNOWN"; // with map String version = computer.flatMap(Computer::getSoundcard) .flatMap(Soundcard::getUSB) .map(USB::getVersion) .orElse("UNKNOWN"); //list
List<String> list = getList(); List<String> listOpt = list != null ? list : new ArrayList<>();
// is equivalent to List<String> listOpt = getList().orElseGet(() -> new ArrayList<>());
|
java9中可以返回另外一个Optional ,使用增强方法ifPresentOrElse :
String defaultString = "default"; Optional<String> value = Optional.empty(); Optional<String> defaultValue = Optional.of(defaultString);
// when Optional<String> result = value.or(() -> defaultValue);
// given Optional<String> value = Optional.of("properValue"); AtomicInteger successCounter = new AtomicInteger(0); AtomicInteger onEmptyOptionalCounter = new AtomicInteger(0); // when value.ifPresentOrElse( v -> successCounter.incrementAndGet(), onEmptyOptionalCounter::incrementAndGet);
|
也增加了stream方法。
Java10中有新的方法叫:orElseThrow
Java11中代码如下:
Optional.of(string).isEmpty()
Stream
Java8 引入了新的Stream:
// starting from list List<String> myList = Arrays.asList("a1", "a2", "b1", "c2", "c1");
myList .stream() .filter(s -> s.startsWith("c")) .map(String::toUpperCase) .sorted() .forEach(System.out::println);
// native stream Stream.of("a1", "a2", "a3") .findFirst() .ifPresent(System.out::println);
|
可以和number和map一起运行:
// working with number IntStream.range(1, 4) .forEach(System.out::println);
// working with map Arrays.stream(new int[] {1, 2, 3}) .map(n -> 2 * n + 1) .average() .ifPresent(System.out::println);
|
流提供者可以多次重用流Stream,从而避免了集合中臭名昭著的错误:
java.lang.IllegalStateException: stream has already been operated upon or closed
Supplier<Stream<String>> streamSupplier = () -> Stream.of("d2", "a2", "b1", "b3", "c") .filter(s -> s.startsWith("a"));
streamSupplier.get().anyMatch(s -> true); // ok streamSupplier.get().noneMatch(s -> true); // ok
|
收集器可以转换到几种List:
List<Person> filtered = persons .stream() .filter(p -> p.name.startsWith("P")) .collect(Collectors.toList());
|
使用flatmap管理nullability
Outer outer = new Outer(); if (outer != null && outer.nested != null && outer.nested.inner != null) { System.out.println(outer.nested.inner.foo); }
// similar to类似上面代码的新写法 Optional.of(new Outer()) .flatMap(o -> Optional.ofNullable(o.nested)) .flatMap(n -> Optional.ofNullable(n.inner)) .flatMap(i -> Optional.ofNullable(i.foo)) .ifPresent(System.out::println);
|
Java9中引入了iterate 和 takeWhile/dropWhile方法:
Stream.iterate(0, i -> i < 10, i -> i + 1) .forEach(System.out::println); System.out.println("stream take while");
Stream<String> stream1 = Stream.iterate("", s -> s + "s") .takeWhile(s -> s.length() < 10); stream1.forEach(System.out::println);
|
Java11引入了Not谓词,以前代码:
lines.stream() .filter(s -> !s.isBlank())
|
现在可以是:
lines.stream() .filter(Predicate.not(String::isBlank))
|
响应式Stream
Java9 引入了java.util.concurrent.Flow的四个接口:
- Flow.Processor
- Flow.Publisher
- Flow.Subscriber
- Flow.Subscription
还有不可变集合:// empty immutable collections List<String> emptyImmutableList = List.of(); Set<String> emptyImmutableSet = Set.of(); Map emptyImmutableMap = Map.of();
// immutable collections List<String> immutableList = List.of("one", "two"); Set<String> immutableSet = Set.of("value1", "value2"); Map<String, String> immutableMap = Map.of("key1", "Value1", "key2", "Value2", "key3", "Value3");
|
Java9引入了MultiResolutionImage和提高了Process API
Java10提高了通过List.copyOf(), Set.copyOf(), Map.copyOf()创建不可变集合能力,Collectors类有了新方法toUnmodifiableList, toUnmodifiableSet, toUnmodifiableMap.
新语法
Java 9 try-with-resource现在支持内部可自定义:
try (new MyAutoCloseable() { }.finalWrapper.finalCloseable) { // do some stuff with finalCloseable } catch (Exception ex) { }
|
Java 9还支持带有菱形运算符的匿名类:
List<String> list = new ArrayList<>(){ };
Java 9支持支持HTTP / 2和websockets的新HTTP客户端API。
Java 11改善了HTTP客户端API支撑
int numLetters = switch (day) { case MONDAY, FRIDAY, SUNDAY -> 6; case TUESDAY -> 7; case THURSDAY, SATURDAY -> 8; case WEDNESDAY -> 9; };
|
Lambdas
Java8中已经引入了Lambda语法:s -> do(s)
为了支持Lambda,引入了5个接口:Consumer, Function, Supplier, Predicate, Operator
在Iterable & Stream & Optional上增加了几个方法:
- forEach
- filter
- map
- flatMap
- collect
- ...
Java 11提高了Lambda的var推断能力
Deprecated
Java 9 short list (https://docs.oracle.com/javase/9/docs/api/deprecated-list.html)
- java.activation
- java.corba
- java.se.ee
- java.transaction
- java.xml.bind
- java.xml.ws
- java.xml.ws.annotation
- jdk.policytool
Java 11 short list
Java EE packages removed
- javax.activation (java.activation)
- javax.activity, javax.rmi, javax.rmi.CORBA, org.omg.* (java.corba)
- javax.transaction (java.transaction)
- javax.xml.bind.* (java.xml.bind)
- javax.jws, javax.jws.soap, javax.xml.soap, javax.xml.ws.*(java.xml.ws)
- javax.annotation (java.xml.ws.annotation)
日志
Java9提供了日志级别和作用域:java -Xlog:all=debug:file=application.log -version
Annotations
Java 8
- @FunctionalInterface : to specify an interface "for lambda" purpose
Java 9
has improved the following annotations
- @SafeVarargs : it improves now private methods
- @Deprecated : it provide the scope of deprecation (JSCOR-GUID-BB859EA8-E6F7-4239-9A52-4F1BDE27BB09>https://docs.oracle.com/javase/9/core/enhanced-deprecation1.htmJSCOR-GUID-BB859EA8-E6F7-4239-9A52-4F1BDE27BB09)