1. JDK

Java Development Kit (JDK) is a Java Development environment. What we commonly refer to as the JDK is the Java SE (Standard Edition) Development Kit. In addition, there are Java EE (Enterprise Edition) and Java ME (Micro Edition Platforms).

1.1 Java Release cycle

version Release time The name of the
JDK Beta 1995 WebRunner
JDK 1.0 1996.1 Oak
JDK 1.1 1997.2
J2SE 1.2 1998.12 playground
J2SE 1.3 2000.5 Kestrel
J2SE 1.4 2002.2 Merlin
J2SE 5.0 2004.9 Tiger
Java SE 6 2006.12 Mustang
Java SE 7 2011.7 Dolphin
Java SE 8(Lts) 2014.3
Java SE 9 2017.9
Java SE 10 2018.3
Java SE 11(Lts) 2018.9
Java SE 12 2019.3
Java SE 13 2019.9
Java SE 14 2020.3
Java SE 15 2020.9

1.2 Important nodes in the development of Java

1995: Alpha and Beta Public versions of Java are released under the name WebRunner.

1996: The first version of Java is released, called Oak. But the first stable release was JDK 1.0.2, called Java 1.

December 8, 1998: J2SE 1.2 was released. This version was renamed Java 2 in J2SE 5.0. SE refers to Standard Edition to distinguish it from J2EE (Enterprise Edition) and J2ME (Micro Edition).

2000.5: J2SE 1.3 was released, including HotSpot JVM. The HotSpot JVM was first released in 1999.4 as the J2SE 1.2 JVM.

2004.9.30: J2SE 5.0 was released. Why is this version named differently from the previous ones? This version was originally planned to be named 1.5, using the same name as before. But to better reflect the maturity of the release, the name was changed to 5.0.

After this release, there is a new version control system, 5.0 for the production release, for the stable J2SE release, and 1.5.0 for the developer release, i.e. Java 5.0 = JDK 1.5.0.

2006.12.11: J2SE was renamed Java SE with.0 removed. Java 6 = JDK 1.6, Java 7 = JDK 1.7.

July, 2011: Java SE 7 was released, a major release update. Many features have been updated.

2018.3: Release of Java SE 10. Prior to that, Java was basically a biannual release, with the exception of Java SE 7, which took five years, and Java SE 8, which took three. After that, new releases were made every six months. However, not every version is LTS (long-term -Support). Oracle plans to release an LTS release every three years. The latest LTS release is Java SE 11.

2. Introduction to Java SE 8 versions

2.1 Java SE 8

2.1.1. Lambda and the functional interface Lambda expressions have been introduced in Java 8 to greatly reduce the amount of code and make the code look cleaner. A functional interface is one that has one and only abstract method, but can have multiple non-abstract methods. Can be implicitly converted to a Lambda expression. We define a functional interface as follows:

@FunctionalInterface
interface Operation {
    int operation(int a, int b);
}
// Define a Class to operate the Operation interface.
class Test {
    private int operate(int a, int b, Operation operation) {
        return operation.operation(a, b);
    }
}

Test test = new Test();
// Prior to Java 8, we wanted to implement the Operation interface and pass it to the test.operate () method. We needed to define an anonymous class that implemented the Operation method.
test.operate(1.2.new Operation() {
    @Override
    public int operation(int a, int b) {
        returna + b; }});// With Lambda expressions, we can write:
test.operate(1.2, (a, b) -> a + b);
Copy the code

2.1.2 Method derivation

With method references, you can point to a method using the name of the method. Use a pair of colons to quote “::” with methods. Using the above example, let’s add a few more methods:

@FunctionalInterface
interface Operation {
    int operation(int a, int b);
}

interface Creater<T> {
    T get(a);
}

interface TestInt {
    int cp(Test test1, Test test2);
}

class Test {
    public static Test create(Creater<Test> creater) {
        return creater.get();
    }

    private int operate(int a, int b, Operation operation) {
        return operation.operation(a, b);
    }

    private static int add(int a, int b) {
        return a + b;
    }

    private int sub(int a, int b) {
        return a - b;
    }

    public int testM(Test test) {
        return 0;
    }

    public void test(TestInt testInt) {
        Test t1 = Test.create(Test::new); 
        Test t2 = Test.create(Test::new); testInt.cp(t1, t2); }}Copy the code

Then there are four corresponding method references:

  • Constructor reference

Usage: Class::new

Test test = Test.create(Test::new);
Copy the code
  • Static method reference

Class::staticMethod

test.operate(1.2, Test::add);
Copy the code
  • Object instance method reference

Instance ::method

test.operate(1.2, test::sub);
Copy the code
  • Class instance method reference

Usage: Class::method

test.test(Test::testM);
Copy the code

The last class instance method reference has two conditions:

  • Satisfy instance methods first, not static methods
  • The first argument to a Lambda expression becomes the object to call the instance method

The test method takes an instance of TestInt, which is represented by a Lambda expression (test t1, test T2) -> res. We call the test method with a reference to test ::testM. Test.test (Test::testM) calls t1.testm (t2).

2.1.3 Interface default methods and static methods

Java 8 adds the default implementation of interfaces, represented by the default keyword. Static default methods can also be provided.

public interface TestInterface {
    String test(a);

    // Interface default method
    default String defaultTest(a) {
        return "default";
    }

    static String staticTest(a) {
        return "static"; }}Copy the code

2.1.4 Repeated notes

Java 8 supports repeated annotations. Prior to Java 8, repeating annotations required some way around the limitation. Take the following code for example.

@interface Author {
    String name(a);
}

@interface Authors {
    Author[] value();
}

@Authors({@Author(name="a"), @Author(name = "b")})
class Article {}Copy the code

In Java 8, you can do this directly.

@Repeatable(Authors.class)
@interface Author {
    String name(a);
}

@interface Authors {
    Author[] value();
}

@Author(name = "a")
@Author(name = "b")
class Article {}Copy the code

Java 8 also provides a new API when parsing annotations.

AnnotatedElement.getAnnotationsByType(Class<T>)
Copy the code

2.1.5 Type Annotations

Before Java 8, annotations could only be used in declarations. In Java 8, annotations could be used anywhere.

@Author(name="a")
private Object name = "";
private String author = (@Author(name="a")String) name;
Copy the code

2.1.6 Better type inference

Java 8 has improved type inference. For example, in Java 7, the following is written:

List<String> stringList = new ArrayList<>();
stringList.add("A");
stringList.addAll(Arrays.<String>asList());
Copy the code

The improved version in Java 8 allows automatic type inference.

List<String> stringList = new ArrayList<>();
stringList.add("A");
stringList.addAll(Arrays.asList());
Copy the code

2.1.7 Optional

The Optional class has been added to Java 8 to address null pointer exceptions. Optional is a container object that can hold NULL. The isPresent() method detects the presence of the value, and the get() method returns the object. In addition, Optional provides many other useful methods to view the documentation. Here is some sample code.

// Create a String container
Optional<String> str = Optional.of("str");
// Whether the value exists
boolean pre = str.isPresent();
Println is called if the value exists, and the method reference to println is passed in
str.ifPresent(System.out::println);
/ / get the value
String res = str.get();
// Pass a null value
str = Optional.ofNullable(null);
// Return the value if it exists, otherwise return the argument passed in
res = str.orElse("aa");
str = Optional.of("str");
// If there is a value, call the mapping function to get the return value, wrap the return value Optional and return it
res = str.map(s -> "aa" + s).get();
// Returns an Optional object with a mapping function
res = str.flatMap(s -> Optional.of(s + "bb")).flatMap(s -> Optional.of(s + "cc")).get();
Copy the code

2.1.8 Stream

The new Stream class in Java 8 provides a new way to handle data. This approach treats the collection of elements as a stream, traveling through a pipeline, passing through a series of processing nodes, and finally outputs the result.

Refer to the API for specific methods that Stream provides. Here is some sample code.

List<String> list = Arrays.asList("maa"."a"."ab"."c");
list.stream()
        .filter(s -> s.contains("a"))
        .map(s -> s + "aa")
        .sorted()
        .forEach(System.out::println);

System.out.println("# # # #");
list.parallelStream().forEach(System.out::println);

List<Integer> numbers = Arrays.asList(1.2.3.4.5.6.7.8);
int res = numbers.stream().map(i -> i + 1).mapToInt(i -> i).summaryStatistics().getMax();
System.out.println(res);
Copy the code

2.1.9 Date and time API

Java 8 has added a new datetime API to enhance the handling of datetime, including LocalDate, LocalTime, LocalDateTime, ZonedDateTime, etc. For details about the API, see the official documentation and this blog.

www.cnblogs.com/muscleape/p…

Here is the sample code.

LocalDate now = LocalDate.now();
System.out.println(now);
System.out.println(now.getYear());
System.out.println(now.getMonth());
System.out.println(now.getDayOfMonth());

LocalTime localTime = LocalTime.now();
System.out.println(localTime);
LocalDateTime localDateTime = now.atTime(localTime);
System.out.println(localDateTime);
Copy the code

2.1.10 Base64 support

Support for Base 64 encoding is provided in the Java 8 standard library. See the available documentation for specific APIS. Here is the sample code.

String base64 = Base64.getEncoder().encodeToString("aaa".getBytes());
System.out.println(base64);
byte[] bytes = Base64.getDecoder().decode(base64);
System.out.println(new String(bytes));
Copy the code

2.1.11 Parallel Array ParallelSort

Parallel operations on arrays, including parallelSort, are available in Java 8, using the API. Arrays.parallelSort(new int[] {1, 2, 3, 4, 5});

2.1.12 Other Features

  • Enhancements to concurrency
  • In Java. Util. Concurrent. Atomic package also adds the following categories:

DoubleAccumulator DoubleAdder LongAccumulator LongAdder

  • The new Nashorn javascript engine is available
  • JJS is a command line tool for Nashorn that can be used to execute JavaScript source code
  • A new class dependency analysis tool, JDEPS, is provided
  • New features for the JVM

The JVM memory permanent area has been replaced by Metaspace (JEP 122). JVM parameters -xx :PermSize and -xx :MaxPermSize are replaced by XX:MetaSpaceSize and -xx :MaxMetaspaceSize. As you can see, The overall improvements in Java 8 are significant, most importantly the introduction of Lambda expressions to simplify code.

Some other improvements are available:

www.oracle.com/technetwork…

Java SE 2.2 9

2.2.1 Jigsaw module system

Prior to Java 9, packaging and dependencies were based on JAR packages. The JRE contains rt.jar, which is nearly 63 meters, which means you would need to rely on a jar package to run a simple Hello World. The modular system, introduced in Java 9, improves on this.

See this article for details on modular systems.

zhuanlan.zhihu.com/p/24800180

2.2.2 JShell REPL

Java 9 provides an interactive interpreter. With JShell, Java can finally run some code in the Shell like Python and Node.js and get results directly.

2.2.3 Private Interface Methods. Private interface methods are used

In Java 9, you can define private methods in interfaces. Example code is as follows:

public interface TestInterface {
    String test(a);

    // Interface default method
    default String defaultTest(a) {
        pmethod();
        return "default";
    }

    private String pmethod(a) {
        System.out.println("private method in interface");
        return "private"; }}Copy the code

2.2.4 Set immutable instance factory method

Previously, we wanted to create an immutable collection by first creating a mutable collection and then using unmodifiableSet to create an immutable collection. The code is as follows:

Set<String> set = new HashSet<>();
set.add("A");
set.add("B");
set.add("C");

set = Collections.unmodifiableSet(set);
System.out.println(set);
Copy the code

Java 9 provides a new API for creating immutable collections.

List<String> list = List.of("A"."B"."C");
Set<String> set = Set.of("A"."B"."C");
Map<String, String> map = Map.of("KA"."VA"."KB"."VB");
Copy the code

2.2.5 improve the try – with – resources

There is no need in Java 9 to define an additional variable in the try. Before Java 9 you needed to use try-with-resources like this:

InputStream inputStream = new StringBufferInputStream("a");
try (InputStream in = inputStream) {
    in.read();
} catch (IOException e) {
    e.printStackTrace();
}
Copy the code

In Java 9, you can use the inputStream variable directly without having to define new variables.

InputStream inputStream = new StringBufferInputStream("a");
try (inputStream) {
    inputStream.read();
} catch (IOException e) {
    e.printStackTrace();
}
Copy the code

2.2.6 Jar packages compatible with multiple versions

Java 9 supports maintaining different versions of Java classes and resources in the same JAR.

2.2.7 Enhanced Stream, Optional, and Process apis

2.2.8 Adding the HTTP2 Client

2.2.9 Enhanced Javadoc with HTML 5 document output and search capabilities

2.2.10 enhance @ Deprecated

New since and forRemoval attributes for Deprecated

2.2.11 Improved the diamond operator “<>” to be used in anonymous inner classes.

Prior to Java 9, internal anonymous classes needed to specify generic types as follows:

Handler<? extends Number> intHandler1 = new Handler<Number>(2) {}Copy the code

In Java 9, type inference can be done automatically, as follows:

Handler<? extends Number> intHandler1 = new Handler<>(2) {}Copy the code

2.2.12 Multi-resolution Image API: Define multi-resolution image API, developers can easily manipulate and display images of different resolutions.

2.2.13 Improved CompletableFuture API

The asynchronous mechanism of the CompletableFuture class can perform an operation when the processhandle. onExit method exits. Some other improvements are available:

Docs.oracle.com/javase/9/wh…

2.3 Java SE 10

2.3.1 Added local type inference var

var a = "aa";
System.out.println(a);
Copy the code

The var keyword can currently only be used in local variables and for loop variable declarations.

2.3.2 Deleting the Javah Tool

Remove the Javah tool from the JDK and use javac -h instead.

2.3.3 Unified garbage collection interface improves GC and other housekeeping management

Other features

JDK 10 introduced a new way to execute callbacks on threads, which makes it convenient to stop a single thread instead of stopping all threads or stopping one at a time.

Java 10 turns on Graal, the Java JIT compiler, as an experimental JIT compiler for Linux/X64 platforms.

Provides the default CA root certificate

The main goal of this JEP is to perform some memory management and combine the many repositories of the JDK ecosystem into a single repository.

Some other improvements can be considered:

www.oracle.com/technetwork…

Java SE 2.4 11

2.4.1 Use var in Lambda

(var x, var y) -> x.process(y)
Copy the code

2.4.2 String API enhancements

Java 11 has a new set of string handling methods, such as:

// Determine if the string is blank
"".isBlank(); 
" Javastack ".stripTrailing();  // " Javastack"
" Javastack ".stripLeading();   // "Javastack "
Copy the code

2.4.3 Standardize the HttpClient API

2.4.4 Directly compile and run Java, eliminating the steps of first compiling javAC to generate class and then running it

2.4.5 Added support for TLS 1.3

2.4.6 New garbage collector ZGC was added, but it was introduced experimentally

The Z garbage collector (also known as the ZGC) is a scalable low-latency garbage collector (JEP 333). It aims to meet the following objectives:

  • The pause time does not exceed 10 milliseconds
  • The pause time does not increase with the size of the heap or active set
  • Handles heaps ranging in size from hundreds of megabytes to several terabytes

At the heart of ZGC is a concurrent garbage collector, which means that all the heavy lifting (markup, compression, reference processing, string table cleanup, and so on) is done while the Java thread continues to execute. This greatly limits the negative impact of garbage collection on application response time. The experimental version of the ZGC has the following limitations:

  • Available only on Linux/X64.
  • Oop and/or compressed class points using compression are not supported. + UseCompressedOops and – – XX: XX: + UseCompressedClassPointers option is disabled by default. Enabling them will not work.
  • Class uninstallation is not supported. + ClassUnloading and – – XX: XX: + ClassUnloadingWithConcurrentMark option is disabled by default. Enabling them will not work.
  • ZGC in combination with Graal is not supported.

Some other improvements can be considered:

www.oracle.com/technetwork…

Java SE 2.5 12

2.5.1 Switch Expressions

After Java 12, switches can be used not only as statements, but also as expressions.

private String switchTest(int i) {
    return switch (i) {
        case 1 -> "1";
        default -> "0";
    };
}
Copy the code

Some other improvements can be considered:

www.oracle.com/technetwork…

Java SE 2.6 13

2.6.1 Starting in Archive Mode

When starting with an archive file, the JVM maps the archive file into its corresponding memory, which contains most of the required classes, and how complex the classloading mechanism is to use. You can even save memory space by sharing memory areas between JVM instances that are running concurrently, freeing up memory wasted when you need to create the same information in each JVM instance. In Java 12, the archive of JDK JAR classes is enabled by default. If you want to disable the archive of JDK JAR classes, you can add:

-Xshare:off
Copy the code

In Java 13, instead of providing a list of archive classes, there is a cleaner way to create an archive containing application classes. You can use the -xx :ArchiveClassesAtExit parameter to control the application to generate an archive upon exit, or use the -xx :SharedArchiveFile parameter to use the dynamic archive function. For details, see the following example. Example of creating an archive file

$ java -XX:ArchiveClassesAtExit=helloworld.jsa -cp helloworld.jar Hello
Copy the code

Use an archive file example

$ java -XX:SharedArchiveFile=hello.jsa -cp helloworld.jar Hello
Copy the code

This is the dynamic archiving of classes at the end of Java application execution, and based on Java 10, multiple commands have been simplified to make it easier to use class archiving.

2.6.2 Switch Expression Extension (Preview function)

Switch expressions were introduced in Java 12 as a preview feature, while Switch expressions were enhanced in Java 13 by introducing yield statements in blocks to return values instead of using breaks. This means that Switch expressions (which return a value) should use yield and Switch statements (which do not return a value) should use break. Until then, it would be more cumbersome to return content in Switch, but it is currently in preview state. Since Java 13, Switch expressions have used the yield keyword to return a value. The difference between return and Switch expressions is that: Return will jump directly out of the current loop or method, whereas yield will jump only out of the current Switch block, and the default condition is required to use yield. Prior to Java 12, traditional Switch statements were written as: traditional

private static String getText(int number) {
    String result = "";
    switch (number) {
        case 1.2:
        result = "one or two";
        break;
        case 3:
        result = "three";
        break;
        case 4.5.6:
        result = "four or five or six";
        break;
        default:
        result = "unknown";
        break;
    };
    return result;
}
Copy the code

After Java 12, the Switch expression is written as follows: tag simplification

private static String getText(int number) {
    String result = switch (number) {
        case 1.2 -> "one or two";
        case 3 -> "three";
        case 4.5.6 -> "four or five or six";
        default -> "unknown";
    };
    return result;
}
Copy the code

In Java 13, instead of compiling the value break statement, yield is used to return the value. This is changed to the yield return value form

private static String getText(int number) {
    return switch (number) {
        case 1.2:
            yield "one or two";
        case 3:
            yield "three";
        case 4.5.6:
            yield "four or five or six";
        default:
            yield "unknown";
    };
}
Copy the code

2.6.3 Text Blocks (Preview)

For a long time, the Java language in the way defined string is limited, the string needs to begin with double quotes, ends in double quotation marks, and this leads to a string will not be able to exercise more, but need to escape a new line or line connector to flexible support multiple lines, but this will increase the editing work, at the same time can also lead to place code difficult to read, and difficult to maintain.

Java 13 introduced text blocks to solve the problem of multiple lines of text. Text blocks begin with triple double quotes and end with the same triple double quotes. Anything between them is interpreted as part of a string, including line breaks, eliminating the need for most escape sequences, It is still a plain java.lang.String object, and the text block can be used anywhere String literals can be used in Java, unchanged from compiled code, and enhances String readability in Java programs. And this way, strings can be represented more intuitively, can span multiple lines without the visual clutter of escaping, and will greatly improve the readability and writability of Java class programs.

Prior to Java 13, multi-line string writing was: multi-line string writing

String html ="<html>\n" +
              " \n" +
              " 

Hello, World

\n"
+ " \n" + "</html>\n"; String json ="{\n" + " \"name\":\"mkyong\",\n" + " \"age\":38\n" + "}\n"; Copy the code

After Java 13 introduced text blocks, it was written as: multi-line text blocks

String html = """   

Hello, World

"
""; String json = """{"name":"mkyong","age": 38}"""; Copy the code

Text blocks were introduced in Java 13 as a preview feature, which means they are not included in the relevant Java language specification. The benefit of this is that users can easily test the feature and provide feedback on which subsequent updates can improve the feature, or even remove it if necessary, if it immediately becomes Java SE

Part of it becomes more difficult to make changes. It is important to realize that the preview feature is not in beta form.

Since preview features are not part of the specification, it is necessary to explicitly enable them for compilation and runtime. The following two command-line arguments are required to enable preview: Listing 8. Enable preview

$ javac --enable-preview --release 13 Example.java
$ java --enable-preview Example
Copy the code

Java SE 2.7 14

2.7.1 Instanceof Mode Matching

Typically, we use Instanceof to detect the true type of a class and cast it if it fits that type. Before Java14, we used to write as follows:

Object obj = "Program new horizon";
if(obj instanceof String){
	String str = (String) obj;
	System.out.println("Concerned Public Account:" + str);
}
Copy the code

With the new java14 features, we can simplify this as follows:

Object obj = "Program new horizon";
if(obj instanceof String str){
	System.out.println("Concerned Public Account:" + str);
}
Copy the code

We can express objects succinctly through pattern matching and allow various statements and expressions to test them.

2.7.2 Introduction of Record Type

Record Types were introduced as a preview feature in Java 14. Record objects allow classes to be declared using a compact syntax, and like enumerated types, records are a limited form of class. In IDEA 2020.1, creating a Record is the same as creating classes and enumerations, and the corresponding type can be directly selected at creation time. Define a Record type as follows:

public record Point(int x, int y) {}Copy the code

Using the Record operation is as follows:

Point point = new Point(1.3);
System.out.println(point.x());
System.out.println(point.y());
Copy the code

Decompiling the Record class shows something like this:

public final class Point extends java.lang.Record {
    private final int x;
    private final int y;

    public Point(int x, int y) { /* compiled code */ }

    public java.lang.String toString(a) { /* compiled code */ }

    public final int hashCode(a) { /* compiled code */ }

    public final boolean equals(java.lang.Object o) { /* compiled code */ }

    public int x(a) { /* compiled code */ }

    public int y(a) { /* compiled code */}}Copy the code