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