您的位置 首页 java

Java14~java8~Java1各大版本中令人激动的特性

现在的 jdk 真变成了“版本帝”,无力吐槽啊,版本发到 15,大部分人却都还在用着 JDK 7/8,甚至 6。不过没关系,多了解一下,多掌握一点新东西,对你来说没有坏处。

Java14

instanceof模式匹配

通常情况下我们使用instanceof来探测类的真实类型,如果符合该类型,则可进行强制转换。

在Java14之前,我们通常的写法如下:

 Object obj = "程序新视界";
if(obj instanceof String){
String str = (String) obj;
System.out.println("关注公众号:" + str);
}
  

通过 java 14的新特性,我们可以简化成如下方式:

 Object obj = "程序新视界";
if(obj instanceof String str){
System.out.println("关注公众号:" + str);
}
  

我们可以通过模式匹配简洁地表达对象,并允许各种语句和表达式对其进行测试。

switch 表达式

通常情况下我们通过如下形式使用switch语法:

 switch (day) {
    case MONDAY:
    case FRIDAY:
    case SUNDAY:
        System.out.println(6);
        break;
    case TUESDAY:
        System.out.println(7);
        break;
    case THURSDAY:
    case SATURDAY:
        System.out.println(8);
        break;
    case WEDNESDAY:
        System.out.println(9);
        break;
}
  

java14引入了新形式的switch标签“case L->”,表示如果匹配,则只执行标签右边的代码。switch标签允许在每种情况下使用逗号分隔多个常量。

 switch (day) {
    case MONDAY, FRIDAY, SUNDAY -> System.out.println(6);
    case TUESDAY                -> System.out.println(7);
    case THURSDAY, SATURDAY     -> System.out.println(8);
    case WEDNESDAY              -> System.out.println(9);
}
  

是不是简单清晰了很多。

记录类型(Record Type)的引入

Java 14中记录类型(Record Type)作为预览特性被引入。记录对象允许使用紧凑的语法来声明类,和枚举类型一样,记录也是类的一种受限形式。

在idea 2020.1中,创建Record与创建类和枚举一样,可以在创建时直接选择对应的类型。

定义一个Record类型如下:

 public record Point(int x, int y) {

}
  

使用Record操作如下:

 Point point = new Point(1,3);
System.out.println(point.x());
System.out.println(point.y());
  

对Record类进行反编译我们会看到如下内容:

 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() { /* compiled code */ }

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

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

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

    public int y() { /* compiled code */ }
}
  

是不是有替代Lombok的潜质?

文本块作为预览特性保留

通常情况下我们定义一个 字符串 ,如果比较长可使用如下形式进行编写:

 String  html  = "<html>\n" +
              "    <body>\n" +
              "        <p>Hello, world</p>\n" +
              "    </body>\n" +
              "</html>\n";
  

使用java14的文本块新特性,则可改写为如下形式:

 String html = """
              <html>
                  <body>
                      <p>Hello, world</p>
                  </body>
              </html>
              """;
  

文本块是Java语言的新语法,可以用来表示任何字符串,具有更高的表达能力和更少的复杂度。

文本块的开头定界符是由三个 双引号 字符(”””)组成的序列,后面跟0个或多个空格,最后跟一个行终止符。内容从开头定界符的行终止符之后的第一个字符开始。

结束定界符是三个双引号字符的序列。内容在结束定界符的第一个双引号之前的最后一个字符处结束。

与字符串文字中的字符不同,文本块的内容中可以直接包含双引号字符。允许在文本块中使用”,但不是必需的或不建议使用。

与字符串文字中的字符不同,内容可以直接包含行终止符。允许在文本块中使用\n,但不是必需或不建议使用。

打包工具 (Incubator)

jpackage打包工具可以将Java应用程序打包为针对特定平台的安装包,这个安装包包含所有必需的依赖项。该应用程序可以以普通JAR文件集合或模块集合的方式提供。软件包格式可以分为:

  • Linux:deb和rpm
  • macOS:pkg和dmg
  • Windows:msi和exe


Java 13

一. 文本块-预览(JEP 355)

这是预览功能。它使我们能够轻松地创建多行字符串。多行字符串必须写在一对三重双引号内。

使用文本块创建的字符串对象没有其他属性。这是创建多行字符串的简便方法。我们不能使用文本块来创建单行字符串。另外,开头的三重双引号后必须跟一个行终止符。

在 Java 13 之前:

 String html ="<html>\n" +
  "   <body>\n" +
  "      <p>Hello, World</p>\n" +
  "   </body>\n" +
  "</html>\n";


String json ="{\n" +
  "   \"name\":\"mkyong\",\n" +
  "   \"age\":38\n" +
  "}\n";
  

Java 13:

 String html =  """
               <html>
                   <body>
                       <p>Hello, World</p>
                   </body>
               </html>
        """;

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

回到顶部

二. 文本块的字符串类新方法

String 类中有三个与文本块功能关联的新方法。

  1. formatted(Object…args) :它类似于 String format() 方法。添加它是为了支持文本块的格式化。
  2. stripIndent() :用于从文本块中的每一行的开头和结尾删除附带的空格字符。文本块使用此方法,并保留内容的相对缩进。
  3. translateEscapes() :返回一个值为该字符串的字符串,其转义序列就像在字符串文字中一样进行翻译。
 package com.journaldev.java13.examples;

public class StringNewMethods {

/***
 * New methods are to be used with Text Block Strings
 * @param args
 */@SuppressWarnings("preview")
public static void main(String[] args) {

String output = """
    Name: %s
    Phone: %d
    Salary: $%.2f
    """.formatted("Pankaj", 123456789, 2000.5555);

System.out.println(output);


String htmlTextBlock = "<html>   \n"+
                    "\t<body>\t\t \n"+
                        "\t\t<p>Hello</p>  \t \n"+
                    "\t</body> \n"+
                "</html>";
System.out.println(htmlTextBlock.replace(" ", "*"));
System.out.println(htmlTextBlock.stripIndent().replace(" ", "*"));

String str1 = "Hi\t\nHello' \" /u0022 Pankaj\r";
System.out.println(str1);
System.out.println(str1.translateEscapes());

}
}
  

输出:

 Name: Pankaj
Phone: 123456789
Salary: $2000.56

<html>***
<body>*
<p>Hello</p>***
</body>*
</html>
<html>
<body>
<p>Hello</p>
</body>
</html>
Hi
Hello' " /u0022 Pankaj
Hi
Hello' " /u0022 Pankaj
  

回到顶部

三. 开关表达式-预览(JEP 354)

Java 12 引入了JEP 325 Switch表达式。该 JEP 放弃 brea 关键字而改用 yield 关键字从 switch 表达式返回值。(其他均与 Java 12 没区别)

 // switch expressions, use yield to return, in Java 12 it was break
int x = switch (choice) {
    case 1, 2, 3:
        yield choice;
    default:
        yield -1;
};
  

(ps:这会在 Java 14 – JEP 361 中成为标准功能)

回到顶部

四. 重新实现旧版套接字 API(JEP 353)

java.net.Socket java.net.ServerSocket 的底层实现都很古老,可以追溯到 JDK 1.0,它混合了遗留的 Java 和 C 代码,很难维护和调试。这个 JEP 为套接字 API 引入了新的底层实现,这是 Java 13 中的默认实现。

在 Java 13 之前, SocketImpl 使用 PlainSocketImpl

 public class ServerSocket implements java.io.Closeable {

    /**
     * The implementation of this Socket.
     */    private SocketImpl impl;
}
  

Java 13 引入了一个新的 NioSocketImpl 类,作为对 PlainSocketImpl 的临时替换。但是,如果出现错误,我们仍然可以通过设置 jdk.net.usePlainSocketImpl 系统属性切换回旧的实现 PlainSocketImpl

下面是一个简单的套接字示例。

 import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

public class JEP353 {

    public static void main(String[] args) {

        try (ServerSocket serverSocket = new ServerSocket(8888)){

            boolean running = true;
            while(running){
                Socket clientSocket = serverSocket.accept();
                //do something with clientSocket
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
  

在 Java 13 中,默认实现是 NioSocketImpl

 D:\test>javac JEP353.java

D:\test>java JEP353

D:\test>java -XX:+TraceClassLoading JEP353  | findStr Socket

[0.040s][info   ][class,load] java.net.ServerSocket source: jrt:/java.base
[0.040s][info   ][class,load] jdk.internal.access.JavaNetSocketAccess source: jrt:/java.base
[0.040s][info   ][class,load] java.net.ServerSocket$1 source: jrt:/java.base
[0.040s][info   ][class,load] java.net.SocketOptions source: jrt:/java.base
[0.040s][info   ][class,load] java.net.SocketImpl source: jrt:/java.base
[0.044s][info   ][class,load] java.net.SocketImpl$$Lambda$1/0x0000000800ba0840 source: java.net.SocketImpl
[0.047s][info   ][class,load] sun.net.PlatformSocketImpl source: jrt:/java.base

[0.047s][info   ][class,load] sun.nio.ch.NioSocketImpl source: jrt:/java.base

[0.047s][info   ][class,load] sun.nio.ch.SocketDispatcher source: jrt:/java.base
[0.052s][info   ][class,load] java.net.SocketAddress source: jrt:/java.base
[0.052s][info   ][class,load] java.net.InetSocketAddress source: jrt:/java.base
[0.052s][info   ][class,load] java.net.InetSocketAddress$InetSocketAddressHolder source: jrt:/java.base
[0.053s][info   ][class,load] sun.net.ext.ExtendedSocketOptions source: jrt:/java.base
[0.053s][info   ][class,load] jdk.net.ExtendedSocketOptions source: jrt:/jdk.net
[0.053s][info   ][class,load] java.net.SocketOption source: jrt:/java.base
[0.053s][info   ][class,load] jdk.net.ExtendedSocketOptions$ExtSocketOption source: jrt:/jdk.net
[0.053s][info   ][class,load] jdk.net.SocketFlow source: jrt:/jdk.net
[0.053s][info   ][class,load] jdk.net.ExtendedSocketOptions$PlatformSocketOptions source: jrt:/jdk.net
[0.053s][info   ][class,load] jdk.net.ExtendedSocketOptions$PlatformSocketOptions$1 source: jrt:/jdk.net
[0.054s][info   ][class,load] jdk.net.ExtendedSocketOptions$1 source: jrt:/jdk.net
[0.054s][info   ][class,load] sun.nio.ch.NioSocketImpl$FileDescriptorCloser source: jrt:/java.base
[0.055s][info   ][class,load] java.net.Socket source: jrt:/java.base
  

回到顶部

五. 动态 CDS 存档(JEP 350)

该 JEP 扩展了 Java 10 中引入的类数据共享功能。现在,创建 CDS 存档并使用它要容易得多。

 $ java -XX:ArchiveClassesAtExit=my_app_cds.jsa -cp my_app.jar

$ java -XX:SharedArchiveFile=my_app_cds.jsa -cp my_app.jar
  

回到顶部

六. ZGC:取消提交未使用的内存(JEP 351)

该 JEP 增强了ZGC,可以将未使用的堆内存返回给操作系统。Z垃圾收集器是 Java 11 中引入的。它会在堆内存清理之前增加一个短暂的暂停时间。但是,未使用的内存没有返回给操作系统。对于诸如 IoT 和微芯片等内存占用较小的设备,这是一个问题。

现在,它已得到增强,可以将未使用的内存返回给操作系统。

回到顶部

七. FileSystems.newFileSystem() 方法

在 FileSystems 类中添加了三种新方法,以便更容易地使用文件系统提供程序,这些提供程序将文件的内容视为文件系统。

  1. newFileSystem(Path)
  2. newFileSystem(Path, Map<String, ?>)
  3. newFileSystem(Path, Map<String, ?>, ClassLoader)

回到顶部

八. 具有命名空间支持的 DOM 和 SAX 工厂

有一些新方法可以实例化支持名称空间的 DOM 和 SAX 工厂。

  1. newDefaultNSInstance()
  2. newNSInstance()
  3. newNSInstance(String factoryClassName, ClassLoader classLoader)
 //java 13 onwards
DocumentBuilder db = DocumentBuilderFactory.newDefaultNSInstance().newDocumentBuilder(); 

// before java 13
DocumentBuilderFactory dbf = DocumentBuilderFactory.newDefaultInstance(); 
dbf.setNamespaceAware(true); 
DocumentBuilder db = dbf.newDocumentBuilder();  

Java 12

switch 表达式

Java 12 以后,switch 不仅可以作为语句,也可以作为表达式。

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

Java 11

1. Lambda 中使用 var

 (var x, var y) -> x.process(y)  

2. 字符串 API 增强

Java 11 新增了 一系列字符串处理方法,例如:

 // 判断字符串是否为空白
" ".isBlank(); 
" Javastack ".stripTrailing();  // " Javastack"
" Javastack ".stripLeading();   // "Javastack "  

3. 标准化 HttpClient API

4. java 直接编译并运行,省去先 javac 编译生成 class 再运行的步骤

5. 增加对 TLS 1.3 的支持

其他一些改进可以参照 #NewFeature


Java 10

1. 新增局部类型推断 var

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

var 关键字目前只能用于局部变量以及 for 循环变量声明中。

2. 删除工具 javah

从JDK中移除了 javah 工具,使用 javac -h 代替。

3. 统一的垃圾回收接口,改进了 GC 和其他内务管理

其他特性

  • ThreadLocal 握手交互
    JDK 10 引入一种在线程上执行回调的新方法,很方便地停止单个线程而不是停止全部线程或者一个都不停。
  • 基于Java的实验性JIT编译器
    Java 10 开启了 Java JIT编译器 Graal,用作Linux / x64平台上的实验性JIT编译器。
  • 提供默认的 CA 根证书
  • 将 JDK 生态整合到单个仓库
    此JEP的主要目标是执行一些内存管理,并将JDK生态的众多存储库组合到一个存储库中。

其他一些改进可以参照 #NewFeature


Java 9

1. Jigsaw 模块系统

在 Java 9 以前,打包和依赖都是基于 JAR 包进行的。JRE 中包含了 rt.jar,将近 63M,也就是说要运行一个简单的 Hello World,也需要依赖这么大的 jar 包。在 Java 9 中提出的模块化系统,对这点进行了改善。 关于模块化系统具体可以看看这篇文章。

2. JShell REPL

Java 9 提供了交互式解释器。有了 JShell 以后,Java 终于可以像 Python,Node.js 一样在 Shell 中运行一些代码并直接得出结果了。

3. 私有接口方法,接口中使用私有方法

Java 9 中可以在接口中定义私有方法。示例代码如下:

 public interface TestInterface {
    String test();

    // 接口默认方法
    default String defaultTest() {
        pmethod();
        return "default";
    }

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

4. 集合不可变实例工厂方法

在以前,我们想要创建一个不可变的集合,需要先创建一个可变集合,然后使用 unmodifiableSet 创建不可变集合。代码如下:

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

set = Collections.unmodifiableSet(set);
System.out.println(set);  

Java 9 中提供了新的 API 用来创建不可变集合。

 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");  

5. 改进 try-with-resources

Java 9 中不需要在 try 中额外定义一个变量。Java 9 之前需要这样使用 try-with-resources:

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

在 Java 9 中可以直接使用 inputStream 变量,不需要再额外定义新的变量了。

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

6. 多版本兼容 jar 包

Java 9 中支持在同一个 JAR 中维护不同版本的 Java 类和资源。

7. 增强了 Stream,Optional,Process API

8. 新增 HTTP2 Client

9. 增强 Javadoc,增加了 HTML 5 文档的输出,并且增加了搜索功能

10. 增强 @Deprecated

对 Deprecated 新增了 since 和 forRemoval 属性

11. 增强了钻石操作符 “<>”,可以在 匿名内部类中使用了。

在 Java 9 之前,内部匿名类需要指定泛型类型,如下:

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

而在 Java 9 中,可以自动做类型推导,如下:

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

12. 多分辨率图像 API:定义多分辨率图像API,开发者可以很容易地操作和展示不同分辨率的图像了。

13. 改进的 CompletableFuture API

CompletableFuture 类的异步机制可以在 ProcessHandle.onExit 方法退出时执行操作。

其他一些改进可参照 #JSNEW-GUID-C23AFD78-C777-460B-8ACE-58BE5EA681F6


Java 8

1. Lambda 和 函数式接口

Lambda 表达式相信不用再过多的介绍,终于在 Java 8 引入了,可以极大的减少代码量,代码看起来更清爽。
函数式接口就是 有且仅有一个抽象方法 ,但是可以有多个非抽象方法的接口。可以隐式转化为 Lambda 表达式。 我们定义一个函数式接口如下:

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

再定义一个 Class 用来操作 Operation 接口。

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

Test test = new Test();  

在 Java 8 之前,我们想要实现 Operation 接口并传给 Test.operate() 方法使用,我们要定义一个匿名类,实现 Operation 方法。

 test.operate(1, 2, new Operation() {
    @Override
    public int operation(int a, int b) {
        return a + b;
    }
});  

而使用 Lambda 表达式,我们就可以这样写了:

 test.operate(1, 2, (a, b) -> a + b);  

2. 方法引用

通过方法引用,可以使用方法的名字来指向一个方法。使用一对冒号来引 “::” 用方法。 还是以上面的例子来看,我们再添加几个方法:

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

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

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);
    }

}  

那么对应的方法引用有四种: 构造方法引用
使用方式:Class::new

 Test test = Test.create(Test::new);  

静态方法引用
使用方式:Class::staticMethod

 test.operate(1, 2, Test::add);  

对象的实例方法引用
使用方式:instance::method

 test.operate(1, 2, test::sub);  

类的实例方法引用
使用方式:Class::method

 test.test(Test::testM);  

其实上面三种方法引用都好理解,最后类的实例方法引用,有两个条件:

  1. 首先要满足实例方法,而不是静态方法
  2. Lambda 表达式的第一个参数会成为调用实例方法的对象 根据这两点我们看上面的例子,test 方法接受一个 TestInt 实例,用 Lambda 表达式表示就是 (Test t1, Test t2) -> res,而我们调用 test 方法时传入的方法引用是 Test::testM,其参数也是一个 Test 实例,最终 test.test(Test::testM) 的调用效果就是 t1.testM(t2)

3. 接口默认方法和静态方法

Java 8 新增了接口的默认实现,通过 default 关键字表示。同时也可以提供静态默认方法。

 public interface TestInterface {
    String test();

    // 接口默认方法
    default String defaultTest() {
        return "default";
    }

    static String staticTest() {
        return "static";
    }
}  

4. 重复注解

Java 8 支持了重复注解。在 Java 8 之前想实现重复注解,需要用一些方法来绕过限制。比如下面的代码。

 @interface Author {
    String name();
}

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

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

而在 Java 8 中,可以直接用下面的方式。

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

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

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

在解析注解的时候,Java 8 也提供了新的 API。

 AnnotatedElement.getAnnotationsByType(Class<T>)  

5. 类型注解

Java 8 之前注解只能用在声明中,在 Java 8 中,注解可以使用在 任何地方。

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

6. 更好的类型推断

Java 8 对于类型推断做了改进。
比如在 Java 7 中下面的写法:

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

在 Java 8 中改进后的写法,可以自动做类型推断。

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

7. Optional

Java 8 中新增了 Optional 类用来解决空指针异常。Optional 是一个可以保存 null 的容器对象。通过 isPresent() 方法检测值是否存在,通过 get() 方法返回对象。
除此之外,Optional 还提供了很多其他有用的方法,具体可以查看文档。下面是一些示例代码。

 // 创建一个 String 类型的容器
Optional<String> str = Optional.of("str");
// 值是否存在
boolean pre = str.isPresent();
// 值如果存在就调用 println 方法,这里传入的是 println 的方法引用
str.ifPresent(System.out::println);
// 获取值
String res = str.get();
// 传入空值
str = Optional.ofNullable(null);
// 如果值存在,返回值,否则返回传入的参数
res = str.orElse("aa");
str = Optional.of("str");
// 如果有值,对其调用映射函数得到返回值,对返回值进行 Optional 包装并返回
res = str.map(s -> "aa" + s).get();
// 返回一个带有映射函数的 Optional 对象
res = str.flatMap(s -> Optional.of(s + "bb")).flatMap(s -> Optional.of(s + "cc")).get();  

8. Stream

Java 8 中新增的 Stream 类提供了一种新的数据处理方式。这种方式将元素集合看做一种流,在管道中传输,经过一系列处理节点,最终输出结果。
关于 Stream 提供的具体方法,可以参照 API。下面是一些示例代码。

 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);  

9. 日期时间 API

Java 8 中新增了日期时间 API 用来加强对日期时间的处理,其中包括了 LocalDate,LocalTime,LocalDateTime,ZonedDateTime 等等,关于 API 可以参照官方文档以及这篇博客,写得很详细。下面是示例代码。

 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);  

10. Base64 支持

Java 8 标准库中提供了对 Base 64 编码的支持。具体 API 见可参照文档。下面是示例代码。

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

11. 并行数组 ParallelSort

Java 8 中提供了对数组的并行操作,包括 parallelSort 等等,具体可参照 API。

 Arrays.parallelSort(new int[] {1, 2, 3, 4, 5});  

12. 其他新特性

  • 对并发的增强 在java.util.concurrent.atomic包中还增加了下面这些类: DoubleAccumulator DoubleAdder LongAccumulator LongAdder
  • 提供了新的 Nashorn javascript 引擎
  • 提供了 jjs,是一个给予 Nashorn 的命令行工具,可以用来执行 JavaScript 源码
  • 提供了新的类依赖分析工具 jdeps
  • JVM 的新特性 JVM内存永久区已经被metaspace替换(JEP 122)。JVM参数 -XX:PermSize 和 –XX:MaxPermSize被XX:MetaSpaceSize 和 -XX:MaxMetaspaceSize代替。

可以看到,Java 8 整体上的改进是很大的,最重要的是引入 Lambda 表达式,简化代码。

其他一些改进可参照

Java SE 7(2011-07-28, codename Dolphin):

JVM 对动态语言的支持

压缩的 64 位指针(可在 Java 6 中使用 -XX:+UseCompressedOops )

Switch 支持 String 类型

try 语句中的自动资源管理

改进在创建泛型对象时应用类型推断

简化 varargs 方法声明

二进制字符串表示整数,允许在字符串表示中添加下划线

捕获多种异常类型并通过改进的类型检查重新抛出异常

Java NIO 新增了对多个文件系统,文件元数据和符号链接的支持,对应软件包:java.nio.file、java.nio.file.attribute、java.nio.file.spi

Timsort 用于对对象的集合和数组进行排序

类库对椭圆曲线密码算法的支持

适用于 Java 2D 的 XRender 管道,改善对 GPU 特定功能的处理

新协议 SCTP 和 Sockets Direct Protocol 的支持

Upstream 对 XML 和 Unicode 的更新

Java 部署规则集

Java SE 6(2006-12-11, codename Mustang):

Sun 用 Java SE 替换了名称 J2SE,并从版本号中删除了”.0″,开发人员的内部编号仍然为1.6.0

不再支持较旧的 Win9x 版本

脚本语言支持

核心平台和 Swing 性能显着提高

通过 JAX-WS改进了 Web 服务支持

JDBC 4.0 支持

Java 编译器 API,允许 Java 程序以编程方式选择和调用 Java 编译器的 API

JAXB 升级到 2.0 版,包括 StAX 解析器的集成

支持可插入注解

GUI 的许多改进

JVM 的改进:同步和编译器性能优化,新算法和对现有垃圾回收算法的升级以及应用程序启动性能

J2SE 5.0(2004-09-30, codename Tiger):

泛型

注解(annotation)

自动装箱/拆箱

枚举

Varargs,用类型名称和三个点来声明方法的最后一个参数,如 void drawtext(String… lines)

增强的 for each 循环

改进了多线程 Java 程序的执行语义,新的 Java 内存模型解决了先前规范的复杂性、有效性和性能问题

静态导入

RMI 对象自动存根生成

Swing 新的外观

并发包 java.util.concurrent

扫描程序类,用于解析输入流和缓冲区的数据

在 Apple Mac OS X 10.4 开始支持

J2SE 1.4(2002-02-06, codename Merlin):

新增 assert 关键字

新增 Perl 正则表达式

提供了异常链,允许封装原始的低级的异常

支持 IPv6

Logging API

Image I/O API

集成 XML 解析器和 XSLT 处理器(JAXP)

集成安全性和加密扩展(JCE,JSSE,JAAS)

Java Web Start

Preferences API

J2SE 1.3(2000-05-08, codename Kestrel):

新增 HotSpot JVM

修改 RMI 支持与 CORBA 的可选兼容性

JNDI (Java Naming and Directory Interface),Java 命名和目录接口

新增 JPDA(Java Platform Debugger Architecture),Java 平台调试器体系架构

Java 声音

合成代理类

J2SE 1.2(1998-12-08, codename Playground):

版本名称改为 “J2SE”,区分 J2EE 和 J2ME

新增类达到 1520 个

Java plug-in

Collections 框架

Swing 图形 API

Java IDL

Sun 的 JVM 首次搭载一台 JIT 编译器

JDK 1.1(1997-02-19):

AWT 事件模型

内部类

JavaBeans

JDBC(Java DataBase Connectivity)

RMI(Remote Method Invocation)

反射(暂不支持实时修改对象属性)

Windows 平台上的 JIT(Just In Time)编译器

Taligent 的国际化和 Unicode 支持

JDK 1.0(1996-01-23,codename Oak):

第一版 JDK,纯解释运行,外挂JIT,运行速度较慢

文章来源:智云一二三科技

文章标题:Java14~java8~Java1各大版本中令人激动的特性

文章地址:https://www.zhihuclub.com/192460.shtml

关于作者: 智云科技

热门文章

网站地图