New features of Java 9-11

1. Performance improvement

Every time the JDK version is upgraded, the JVM speed will be improved. The performance improvement of jdk9-11 JVM is mainly reflected in garbage collection;

garbage collector :

  • The default configuration of java8 is UseParallelGC. The default value of the virtual machine running in Server mode. Use the collector combination of Parallel Scavenge + Serial Old for memory reclamation. Many projects use useonemarksweepgc. Use the collector combination of ParNew + CMS + Serial Old for memory reclamation. The Serial Old collector will be used as a backup collector after the CMS collector fails in concurrent mode. CMS is removed from java14;
    //**View GC configuration
    java -XX:+PrintCommandLineFlags -version
    
  • The default configuration of java9 is UseG1GC. Use G1 collector for memory recovery;
  • java10 improves G1 collector, allows parallel Full GC, and improves G1 latency. G1 will try to avoid Full GC, but Full GC will still appear. java10 uses a parallel mark clear compress algorithm. The number of threads can be configured with - XX:ParallelGCThreads.
  • Java 11 introduces the configuration of useepsilon GC. Use Epsilon garbage collector for memory reclamation. It is an inoperative garbage collector that handles memory allocation but does not implement any actual memory recycling mechanism. Once the available heap memory is used up, the JVM will exit;
  • Java 11 introduces the configuration UseZGC. Use the ZGC garbage collector for memory reclamation. It is a scalable low latency garbage collector, but it is still experimental. It is not recommended to use the production environment;

2. Grammatical features

java9

Set factory method

Set factory method (creating immutable sets) simplifies the code of creating sets, especially Map;

public class MyCollections {

    //**Simplified code collection
    public static void test() {
        List list = List.of(1, 2, 3);
        System.out.println(list);

        Set set = Set.of(1, 2, 3);
        System.out.println(set);

        Map map = Map.of("key1", "value1", "key2", "value2");
        System.out.println(map);
    }
}

Completabilefuture new method

public class MyCompletableFuture {

    public static void main(String[] args) throws Exception {
        //**Factory method, which returns the completable future completed abnormally
        CompletableFuture<String> future1 = CompletableFuture.failedFuture(new RuntimeException("error"));
        //future1.get();

        CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> {
            try {
                TimeUnit.SECONDS.sleep(5);
            } catch (Exception ignored) {}

            return "pings1";
        });
        //**If future2 can be completed within a given time, the return value of future2 will be returned; otherwise, the default value will be returned
        //CompletableFuture<String> future3 = future2.completeOnTimeout("pings2", 4, TimeUnit.SECONDS);
        //System.out.println(future3.get());

        //**If future2 can be completed within a given time, the return value of future2 will be returned; otherwise, it will be completed with TimeoutException
        CompletableFuture<String> future4 = future2.orTimeout(4, TimeUnit.SECONDS);
        System.out.println(future4.get());
    }
}

Generic improvement

public class MyGenerics {

    interface MyClass<T> {
        T get();
        T get1();
    }

    public static void main(String[] args) {
        //**Anonymous class generic inference
        MyClass<String> myClass = new MyClass<>() {
            @Override
            public String get() {
                return "pings";
            }

            @Override
            public String get1() {
                return "pings1";
            }
        };

        System.out.println(myClass.get());
    }
}

Interface private method

Now the difference between interface and abstract method:

  • Abstract methods can define properties of various scopes, and interfaces can only define public static properties
  • Abstract methods can define methods of various scopes, and interfaces can only define the default implementation of private and public methods
public interface MyInterface {
    private void b() {
        //**You can use this keyword
        System.out.println("b: " + this.getClass().getSimpleName());
    }

    class MyInterfaceImpl implements MyInterface { }

    static void main(String[] args) {
        MyInterface myInterface = new MyInterfaceImpl();
        myInterface.b();
    }
}

Optional new method

public class MyOptional {

    public static void main(String[] args) {
        //**Optional.stream
        List<Optional<String>> list = List.of(Optional.of("A"), Optional.empty(), Optional.of("B"));
        list.stream().flatMap(Optional::stream).forEach(System.out::println);

        //**Optional.ifPresentOrElse
        List<Integer> list1 = List.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
        Optional<Integer> optional = list1.stream().filter(i -> i > 5).findAny();
        optional.ifPresentOrElse(System.out::println, () -> { throw new IllegalArgumentException(); });

        //**Optional.or, which is different from orElseGet: the orElseGet parameter returns the type of optional wrapper, and or still returns optional
        optional = list1.stream().filter(i -> i > 10).findAny();
        Optional optional1 = optional.or(() -> Optional.of(100));
        int rst = optional.orElseGet(() -> 100);
        System.out.println(optional1.get());
        System.out.println(rst);
    }
}

New method of stream

public class MyStream {

    public static void main(String[] args) {
        List<Integer> list = List.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

        //**takeWhile, returns the element that matches the expression until it does not meet the expression for the first time
        List<Integer> list1 = list.stream().takeWhile(i -> i < 5).collect(toList());
        System.out.println(list1);

        //**dropWhile, delete the elements of the expression until the expression is not satisfied for the first time
        List<Integer> list2 = list.stream().dropWhile(i -> i < 5 || i > 9).collect(toList());
        System.out.println(list2);

        //**for(int i = 1; i < 10; i +=2)
        IntStream.iterate(1, x -> x < 10, x -> x + 2).forEach(System.out::println);
        Stream.iterate("ping", s -> s.length() < 10, s -> s = s + "1").forEach(System.out::println);

        //**The element does not support list, so I don't know what the actual use is
        Stream.ofNullable(null).forEach(System.out::println);
        //**This method can avoid null pointer when list3 is null, which still feels useless
        List list3 = null;
        List<Integer> list4 = List.of(1, 2);
        Stream.ofNullable(list3).flatMap(List::stream).forEach(System.out::println);
        Stream.ofNullable(list4).flatMap(List::stream).forEach(System.out::println);
    }
}

Try with resources improvement

public class MyTryWithResources {

    public static void main(String[] args) throws IOException {
        Reader reader = new StringReader("pings");
        BufferedReader br = new BufferedReader(reader);

        //**Compared with the improvement of jdk7, the external variable br can be referenced. Br must be final
        try (reader; br) {
            System.out.println(br.readLine());
        }
    }
}

java10

Collection copyOf static method

public class MyCollections {

    //**The set factory method simplifies the code for creating sets
    public static void test() {
        var list = List.of(1, 2, 3);
        var newList = List.copyOf(list);
        System.out.println(newList);

        var map = Map.of("key1", "value1", "key2", "value2");
        System.out.println(Map.copyOf(map));
    }

    public static void main(String[] args) {
        test();
    }
}

Local variable type inference

var is introduced as the inference identifier of local variable type, which is only applicable to local variables and cannot be used for method formal parameters, constructor formal parameters, method return type, catch formal parameters or any other type of variable declaration;

public class MyVar {

    public static void main(String[] args) {
        var ss = 123;

        //**The type of generics can be inferred
        var list = List.of(1, 2, 3, 4);
        var newList = list.stream().map(Integer::getClass).collect(toList());
        System.out.println(newList);
    }
}

java11

String addition method

public class MyString {

    public static void main(String[] args) {
        String str = "pings";

        boolean isBlank = str.isBlank();  //**Judge whether the string is blank
        System.out.println(isBlank);
        //str = null;
        //System.out.println(str.isBlank()); //** Can't judge non null, I thought I could replace stringutils Isblank() method

        boolean isEmpty = str.isEmpty();  //Judge whether the string is empty
        System.out.println(isEmpty);

        String result1 = str.strip();    //**First blank
        String result2 = str.stripTrailing();  //**Remove trailing blanks
        String result3 = str.stripLeading();  //**Remove header blank

        System.out.println("12".repeat(5));  //**Copy string several times
        str.lines().forEach(System.out::println);  //**Read by line
    }
}

Local variable type inference enhancement

var can be referenced to the parameters of lambda expression;

public class MyVar {

    public static void main(String[] args) {
        //**var can be referenced to the parameters of lambda expression. Originally, the parameters of lambda expression can be written without type. What's the use of writing in this way
        Consumer<String> consumer1 = (var t) -> System.out.println(t.toUpperCase());
        consumer1.accept("pings");

        //**If you want to annotate the parameters of a lambda expression, you must have a type
        //**The function is to define the parameter type when annotating the parameters of lambda expression
        Consumer<String> consumer2 = (@Deprecated var t) -> System.out.println(t.toUpperCase());
        consumer2.accept("pings");
    }
}

HttpClient

public class MyHttpClient {

    public static void test() throws Exception {
        HttpClient client = HttpClient.newHttpClient();
        HttpRequest request = HttpRequest.newBuilder(URI.create("http://www.baidu.com")).build();
        HttpResponse.BodyHandler<String> handler = HttpResponse.BodyHandlers.ofString();

        //**Synchronous call
        //HttpResponse<String> response = client.send(request, handler);
        //String body = response.body();

        //**Asynchronous call
        CompletableFuture<HttpResponse<String>> response = client.sendAsync(request, handler);
        HttpResponse<String> result = response.get();
        String body = result.body();

        System.out.println(body);
    }
}

3. Source code

java9-11 new feature exercise source code

Tags: Java jdk11

Posted by Nixon on Mon, 16 May 2022 19:22:18 +0300