從 java 8到 java 11變化一覽
本文列舉了從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)
相關文章
- 從Java到Kotlin(一)JavaKotlin
- Java 17 與 Java 11 相比有什麼變化?Java
- Java集合從菜鳥到大神演變Java
- Java從8到21的語言新特性Java
- Java 8 中 ArrayList 的變化原始碼分析Java原始碼
- 從 Java 程式碼到 Java 堆Java
- Netflix是如何從java8遷移到Java11? - carlJava
- Java8新特性——從Lambda表示式到Stream流Java
- 從Android到JavaAndroidJava
- 從C++到javaC++Java
- 從 Java 到 Scala(一):物件導向談起Java物件
- 從Java到Kotlin(八)JavaKotlin
- 從 Java 到 Scala(二):objectJavaObject
- 從Java到Kotlin(三)JavaKotlin
- 從Java到Kotlin(四)JavaKotlin
- 從Java到Kotlin(二)JavaKotlin
- 從Java到Kotlin(六)JavaKotlin
- 從Java到Kotlin(五)JavaKotlin
- 從Java到Kotlin(七)JavaKotlin
- 從Java到Node.jsJavaNode.js
- 從Java到Kotlin,然後又回到Java!JavaKotlin
- 一覽js模組化:從CommonJS到ES6JS
- Java 11 究竟比 8 快了多少?Java
- 從 Java 到 Scala(四):TraitsJavaAI
- Java 8 之 lambda 變數作用域Java變數
- 從Java到JVM到OS執行緒睡眠JavaJVM執行緒
- Java 8-13版本功能差異一覽指南 - marcobehlerJava
- JAVA從入門到大神(JAVA——API知識總結)JavaAPI
- 碎片化學習Java(三)-- Java定義變數Java變數
- Java 8 的新特性和改進總覽Java
- java 從EXCEL匯入到系統JavaExcel
- Java學習從入門到精通Java
- Java之美[從菜鳥到高手演變]之面試複習提綱Java面試
- JAVA學習資源一覽Java
- Java之美[從菜鳥到高手演變]之執行緒同步的引入Java執行緒
- Java 8 併發: 原子變數和 ConcurrentMapJava變數
- Java 8 + 10 = Java 18Java
- Java 從入門到精通-反射機制Java反射