转载

从 java 8到 java 11变化一览

本文列举了从Java8到11各个变化的API:

变量

从Java 10开始,开发人员可以选择让编译器使用var来推断类型:

<b>var</b> x=1.0/2.0

<b>var</b> list = <b>new</b> ArrayList<String>();  

<b>var</b> stream = list.stream();


<font><i>// Type inference can be (Java 8)</i></font><font>
Function helloFunction = s -> </font><font>"Hello "</font><font> + s;
 
</font><font><i>// Inference of generics (Diamond Operator, since Java 7)</i></font><font>
List strings = <b>new</b> ArrayList<>();
strings.add(helloFunction.apply(</font><font>"World"</font><font>));
 
</font><font><i>// Inference of generics (Diamond Operator) with anonymous inner classes (Java 9 -> JEP 213)</i></font><font>
Consumer printer = <b>new</b> Consumer<>() {
    @Override
    <b>public</b> <b>void</b> accept(String string) {
        System.out.println(string);
    }
};
strings.forEach(printer::accept);
</font>

Java11已经提高了lambda中的var能力:

IntFunction<Integer> doubleIt1 = (<b>int</b> x) -> x * 2; <font><i>// OK Java 10 and 11</i></font><font>
IntFunction<Integer> doubleIt2 = (<b>var</b> x) -> x * 2; </font><font><i>// OK Java 11</i></font><font>
</font>

更复杂案例:

/ /Inference of parameters in Lambda expressions
Consumer<String> printer = (<b>var</b> s) -> System.out.println(s); <font><i>// statt s -> System.out.println(s);</i></font><font>
 
</font><font><i>// But no mixture of "var" and declarated types possible</i></font><font>
</font><font><i>// BiConsumer<String, String> printer = (var s1, String s2) -> System.out.println(s1 + " " + s2);</i></font><font>
 
</font><font><i>// Useful for type annotations</i></font><font>
BiConsumer<String, String> printer = (@Non<b>null</b> <b>var</b> s1, @Nullable <b>var</b> s2) -> System.out.println(s1 + (s2 == <b>null</b> ? </font><font>""</font><font> : </font><font>" "</font><font> + s2));

</font><font><i>// given</i></font><font>
Optional<String> value = Optional.of(</font><font>"properValue"</font><font>);
AtomicInteger successCounter = <b>new</b> AtomicInteger(0);
 
AtomicInteger onEmptyOptionalCounter = <b>new</b> AtomicInteger(0);
 
</font><font><i>// when</i></font><font>
value.ifPresentOrElse(
   v -> successCounter.incrementAndGet(), 
   onEmptyOptionalCounter::incrementAndGet);
</font>

String新方法

java 8加入新方法join:

Set<String> set1 = Set.of(<font>"a"</font><font>,</font><font>"b"</font><font>, </font><font>"c"</font><font>);
List<String> list1 = List.of(</font><font>"a"</font><font>,</font><font>"b"</font><font>, </font><font>"c"</font><font>);
  
System.out.println( String.join(</font><font>"a"</font><font>, </font><font>"b"</font><font>, </font><font>"c"</font><font>) );
System.out.println( String.join(</font><font>"."</font><font>, set1) );
System.out.println( String.join(</font><font>"."</font><font>, list1) );
</font>

Java9 有了一个返回Stream的新方法

Java11 添加了更多String的新方法:

String.repeat(<b>int</b>)
String.lines()
String.strip()
String.stripLeading()
String.stripTrailing()
String.isBlank()

接口

java8:

  1. 常量Constant variables
  2. 抽象方法Abstract methods
  3. 默认方法Default methods
  4. 静态方法Static methods

Java9:

  1. Constant variables
  2. Abstract methods
  3. Default methods
  4. Static methods
  5. 私有方法Private methods
  6. 私有静态方法Private Static methods

Java11:

看一个接口的完整代码:

<font><i>//generic interface with one type parameter T</i></font><font>
<b>interface</b> SomeInterface<T> { 
 <b>int</b> SOME_CONSTANT = 35; </font><font><i>// variable declaration</i></font><font>
 <b>int</b> abstractMethod(<b>int</b> x, <b>int</b> y);   </font><font><i>// method declaration</i></font><font>
 T abstractMethodUsingGenericType(T[] array, <b>int</b> i); </font><font><i>// method using type parameter</i></font><font>
 <b>default</b> <b>int</b> <b>default</b>Method(<b>int</b> x, <b>int</b> y) {
     </font><font><i>// implementation of method</i></font><font>
  <b>return</b> 0;
 }
 <b>static</b> <b>void</b> main(String[] args) {
     </font><font><i>// any static method, including main can be included in interface</i></font><font>
 }
 
 
 <b>private</b> <b>void</b> <b>private</b>Method(String[] args) {
     </font><font><i>// any private  method can be included in interface</i></font><font>
 }
 
 <b>private</b> <b>static</b> <b>void</b> <b>static</b>Method(String[] args) {
     </font><font><i>// any private static method can be included in interface</i></font><font>
 }
 
  </font><font><i>// nested class definition</i></font><font>
 <b>class</b> NestedClass { 
     </font><font><i>// members of a class</i></font><font>
 }
 </font><font><i>// nested interface definition</i></font><font>
 <b>interface</b> NestedInterface { 
     </font><font><i>// member of an interface</i></font><font>
 }
</font><font><i>// nested enum definition</i></font><font>
 enum NestedEnum {   
     OBJECT1,
     OBJECT2,
     ;
     </font><font><i>// methods, variables and constructors</i></font><font>
 }
  </font><font><i>// nested annotation definition</i></font><font>
 @<b>interface</b> NestedAnnotation {   
     String attrib1();
 }
}
</font>

Nullable管理

java8引入了新的Optional。

<font><i>// return an optional empty object</i></font><font>
Optional<String> optional = Optional.empty();

</font><font><i>// return an optional with value object</i></font><font>
String str = </font><font>"value"</font><font>;
Optional<String> optional = Optional.of(str);

</font><font><i>// return an optional with or without value </i></font><font>
Optional<String> optional = Optional.ofNullable(getString());
</font><font><i>// how to solve String version = computer?.getSoundcard()?.getUSB()?.getVersion() ?: "UNKNOWN";</i></font><font>
</font><font><i>// with map</i></font><font>
String version = computer.flatMap(Computer::getSoundcard)
                            .flatMap(Soundcard::getUSB)
                            .map(USB::getVersion)
                            .orElse(</font><font>"UNKNOWN"</font><font>);
</font><font><i>//list</i></font><font>

List<String> list = getList();
List<String> listOpt = list != <b>null</b> ? list : <b>new</b> ArrayList<>();

</font><font><i>// is equivalent to</i></font><font>
List<String> listOpt = getList().orElseGet(() -> <b>new</b> ArrayList<>());
</font>

java9中可以返回另外一个Optional ,使用增强方法ifPresentOrElse :

String defaultString = <font>"default"</font><font>;
Optional<String> value = Optional.empty();
Optional<String> defaultValue = Optional.of(defaultString);

</font><font><i>// when</i></font><font>
Optional<String> result = value.or(() -> defaultValue);


</font><font><i>// given</i></font><font>
Optional<String> value = Optional.of(</font><font>"properValue"</font><font>);
AtomicInteger successCounter = <b>new</b> AtomicInteger(0);
 
AtomicInteger onEmptyOptionalCounter = <b>new</b> AtomicInteger(0);
 
</font><font><i>// when</i></font><font>
value.ifPresentOrElse(
   v -> successCounter.incrementAndGet(), 
   onEmptyOptionalCounter::incrementAndGet);
</font>

也增加了stream方法。

Java10中有新的方法叫:orElseThrow

Java11中代码如下:

Optional.of(string).isEmpty()

Stream

Java8 引入了新的Stream:

<font><i>// starting from list</i></font><font>
List<String> myList =
    Arrays.asList(</font><font>"a1"</font><font>, </font><font>"a2"</font><font>, </font><font>"b1"</font><font>, </font><font>"c2"</font><font>, </font><font>"c1"</font><font>);

myList
    .stream()
    .filter(s -> s.startsWith(</font><font>"c"</font><font>))
    .map(String::toUpperCase)
    .sorted()
    .forEach(System.out::println);

</font><font><i>// native stream </i></font><font>
Stream.of(</font><font>"a1"</font><font>, </font><font>"a2"</font><font>, </font><font>"a3"</font><font>)
    .findFirst()
    .ifPresent(System.out::println);
</font>

可以和number和map一起运行:

<font><i>// working with number</i></font><font>
IntStream.range(1, 4)
    .forEach(System.out::println);

</font><font><i>// working with map</i></font><font>
Arrays.stream(<b>new</b> <b>int</b>[] {1, 2, 3})
    .map(n -> 2 * n + 1)
    .average()
    .ifPresent(System.out::println);
</font>

流提供者可以多次重用流Stream,从而避免了集合中臭名昭著的错误:

java.lang.IllegalStateException: stream has already been operated upon or closed

Supplier<Stream<String>> streamSupplier =
    () -> Stream.of(<font>"d2"</font><font>, </font><font>"a2"</font><font>, </font><font>"b1"</font><font>, </font><font>"b3"</font><font>, </font><font>"c"</font><font>)
            .filter(s -> s.startsWith(</font><font>"a"</font><font>));

streamSupplier.get().anyMatch(s -> <b>true</b>);   </font><font><i>// ok</i></font><font>
streamSupplier.get().noneMatch(s -> <b>true</b>);  </font><font><i>// ok</i></font><font>
</font>

收集器可以转换到几种List:

List<Person> filtered =
    persons
        .stream()
        .filter(p -> p.name.startsWith(<font>"P"</font><font>))
        .collect(Collectors.toList());
</font>

使用flatmap管理nullability

Outer <b>outer</b> = <b>new</b> Outer();
<b>if</b> (<b>outer</b> != <b>null</b> && <b>outer</b>.nested != <b>null</b> && <b>outer</b>.nested.<b>inner</b> != <b>null</b>) {
    System.out.println(<b>outer</b>.nested.<b>inner</b>.foo);
}

<font><i>// similar to类似上面代码的新写法</i></font><font>
Optional.of(<b>new</b> Outer())
    .flatMap(o -> Optional.ofNullable(o.nested))
    .flatMap(n -> Optional.ofNullable(n.<b>inner</b>))
    .flatMap(i -> Optional.ofNullable(i.foo))
    .ifPresent(System.out::println);
</font>

Java9中引入了iterate 和 takeWhile/dropWhile方法:

Stream.iterate(0, i -> i < 10, i -> i + 1) .forEach(System.out::println);
System.out.println(<font>"stream take while"</font><font>);


Stream<String> stream1 = Stream.iterate(</font><font>""</font><font>, s -> s + </font><font>"s"</font><font>)
      .takeWhile(s -> s.length() < 10);
  
stream1.forEach(System.out::println);
</font>

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

还有不可变集合:

<font><i>// empty immutable collections</i></font><font>
 List<String> emptyImmutableList = List.of();
 Set<String> emptyImmutableSet = Set.of();
 Map emptyImmutableMap = Map.of();

</font><font><i>// immutable collections</i></font><font>
List<String> immutableList = List.of(</font><font>"one"</font><font>, </font><font>"two"</font><font>);
Set<String> immutableSet = Set.of(</font><font>"value1"</font><font>, </font><font>"value2"</font><font>);
Map<String, String> immutableMap = Map.of(</font><font>"key1"</font><font>, </font><font>"Value1"</font><font>, </font><font>"key2"</font><font>, </font><font>"Value2"</font><font>, </font><font>"key3"</font><font>, </font><font>"Value3"</font><font>);
</font>

Java9引入了MultiResolutionImage和提高了Process  API

Java10提高了通过List.copyOf(), Set.copyOf(), Map.copyOf()创建不可变集合能力,Collectors类有了新方法toUnmodifiableList, toUnmodifiableSet, toUnmodifiableMap.

新语法

Java 9 try-with-resource现在支持内部可自定义:

<b>try</b> (<b>new</b> MyAutoCloseable() { }.finalWrapper.finalCloseable) {
     <font><i>// do some stuff with finalCloseable</i></font><font>
  } <b>catch</b> (Exception ex) { }
</font>

Java 9 还支持带有菱形运算符的匿名类:

List<String> list = new ArrayList<>(){ };

Java 9 支持支持HTTP / 2和websockets的新HTTP客户端API。

Java 11 改善了HTTP客户端API支撑

<b>int</b> numLetters = <b>switch</b> (day) {
    <b>case</b> MONDAY, FRIDAY, SUNDAY -> 6;
    <b>case</b> TUESDAY                -> 7;
    <b>case</b> THURSDAY, SATURDAY     -> 8;
    <b>case</b> 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)

  1. java.activation
  2. java.corba
  3. java.se.ee
  4. java.transaction
  5. java.xml.bind
  6. java.xml.ws
  7. java.xml.ws.annotation
  8. 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 ( https://docs.oracle.com/javase/9/core/enhanced-deprecation1.htm#JSCOR-GUID-BB859EA8-E6F7-4239-9A52-4F1BDE27BB09 )
原文  https://www.jdon.com/50890
正文到此结束
Loading...