java11学习

阅读数:62 评论数:0

跳转到新版页面

分类

python/Java

正文

一、概述

java11之前的一个LTS版本是Java8,从版本11开始,Oracle JDK只能由开发人员免费使用,公司需要与Oracle签订有偿支持合同。

二、新特性

1、lambda参数的局部变量语法

即:允许在隐式类型lambda表达式的参数中使用“var”。

以一个例子来说明:

(1)一个显示类型的lambda表达式,显示表示指定了参数l和s的数据类型

(List<String> l, String s) -> l.add(s);

(2)编译器可以从上下文推出参数类型,所以可以转为隐式表达式

(l, s) -> l.add(s);

(3)但有时,有些注解需要放在参数的类型上,而不能直接放在名称上,所以有了var的需要。

(@Nonnull List<String> l, @Nullable String s) -> l.add(s);
//就可以改写成
(@Nonnull var l, @Nullable var s) -> l.add(s);

这三种风格:为所有变量指定类型、省略所有类型、对所有变量使用var,不能混用,最终选择开发者自己选择。

2、http客户端

包括新的HttpClient类,简化了HTTP的使用。

3、新的Collection.toArray()方法

在Java 11之前,Collection接口提供了两个toArray()方法将集合转换为数组。

List<String> list = List.of("foo", "bar", "baz");

Object[] strings1 = list.toArray();

String[] strings2a = list.toArray(new String[list.size()]);
String[] strings2b = list.toArray(new String[0]);

第一个toArray()方法(不带参数)返回一个Object数组。

第二个toArray()方法需要一个请求类型的数组,如果此数组至少与集合一样大,则元素将存储在此数组中(strings2a),否则将创建所需大小的新数组(strings2b)。

从java 11开始,我们还可以这样写:

String[] strings = list.toArray(String[]::new);

4、为String类添加了一些新方法

 isBlank、lines、strip、stripLeading、stripTrailing、repeat。

5、新的文件方法

通过使用Files类中的新的readString和writeString静态方法可以更容易的从文件中读取和写入字符串。

Path filePath = Files.writeString(Files.createTempFile(tempDir, "demo", ".txt"), "Sample text");
String fileContent = Files.readString(filePath);
assertThat(fileContent).isEqualTo("Sample text");

6、Path.of()

之前,我们必须通过Paths.get()或File.toPath()创建Path对象,java 11开始,可以使用Path.of()。

// Relative path foo/bar/baz
Path.of("foo/bar/baz");
Path.of("foo", "bar/baz");
Path.of("foo", "bar", "baz");

// Absolute path /foo/bar/baz
Path.of("/foo/bar/baz");
Path.of("/foo", "bar", "baz");
Path.of("/", "foo", "bar", "baz");

7、一个新的垃圾回收器:Epsilon GC

-XX:+UseEpsilonGC

此GC只进行内存分配,不进行内存回收。

8、启动单文件源代码程序

假设有一个名为Hello.java

public class Hello {
  public static void main(String[] args) {
    if (args.length > 0) {
      System.out.printf("Hello %s!%n", args[0]);
    } else {
      System.out.println("Hello!");
    }
  }
}

在java 11之前,运行它

$ javac Hello.java
$ java Hello Bob

Hello Bob!

从java 11之后,可以

$ java Hello.java Bob

Hello Bob!

在Linux和macOS上,我们可以直接编写可执行的java脚本 (不要使用.java扩展名)。

#!/usr/bin/java --source 11

public class Hello {
  public static void main(String[] args) {
    if (args.length > 0) {
      System.out.printf("Hello %s!%n", args[0]);
    } else {
      System.out.println("Hello!");
    }
  }
}

9、引入嵌套的概念和访问规则

示例代码:

(1)假设有一段代码

public class Outer {

    private void outerPrivate() {

    }

    class Inner {

        public void innerPublic() {
            outerPrivate(); // access Outer's private method!
        }
    }
}

我们在编译上面的源码时,会生成两个类:Outer和Outer$Inner。

(2)内部类可以访问外部类的私有属性,破坏了jvm访问规则

JVM访问规则不允许一个类访问另一个类的私有属性,但是却允许内部类访问外部的的私有属性。

这是Java编译器创建了一个桥接文件 access$000,生成了类似如下的代码:

public class Outer {
  private void outerPrivate() {

  }
  void access$000(){
    outerPrivate();
  }
}

class Inner {
  final Outer obj; 
  public void innerPublic() {
      obj.access$000(); // access Outer's private method!
  }
}

(3)使用反射时会出现的问题

public void innerPublicReflection(Outer ob) throws Exception {
    Method method = ob.getClass().getDeclaredMethod("outerPrivate");
    method.invoke(ob);
}

当我们尝试从Inner类反射地调用outerPrivate是不允许的。

java.lang.IllegalAccessException: 
class Outer$Inner cannot access a member of class Outer with modifiers "private"

java11中,在类文件中包含了两个属性:

NestMembers 标识其包含的静态已知的嵌套成员
NestHost 标识其嵌套宿主

现在编译器不再生成桥接访问,反射的使用也正常。




相关推荐

1、基本类型 在程序设计中经常用到一系列类型(基本类型),它们需要特殊对待。对于这些类型,Java采取与C和C++相同的方法,也就是说,不用new来创建变量,于是创建一个并非引

1、直接常量 为了编译器可以准确的知道要生成什么样的类型,可以给直接常量后面添加后缀字符标志它的类型,若为L表示long,F表示float,D表示double。也可以利用前缀表示进制,0x表示十六进制

Java完全采用动态内存分配方式。每当想创建新对象时,就需要使用new关键字来构建此对象实例。 1、this 在构造器中,如果为this添加了参数列表,那么就有了

一、类的继承 1、说明 (1)extends关键字用于类的继承。 (2)在C++中,方法的动态绑定是使用virtual关键字来实现的,而在Java中,动态绑定是默认的形为,不需要添加额外的关键字。 (

1、类型信息 指程序能够在运行时发现和使用类型信息,我们一般使用两种方式来实现运行时对象和类的信息:传统的RTTI和反射机制。 (1)class对象 <p

用于描述Java源代码,使得我们能够以将由编译器来测试和验证的格式,存储有关程序的额外信息。使用时在@后面跟注解的名字。 1、预定义的三个注解<

一、创建线程 创建线程有四种方式:继承Thread类、实现Runnable接口、实现Callable接口、通过线程池创建。 1、继承Thread 重写run方法。 class A extends Th

一、Collection接口 Collection接口的iterator和toArray方法都用于获得集合中的“所有元素”。前者返回一个“iterator”对象,后者返回一个包含集合中所有元素的数组。

1.hashCode的存在主要用于查找的快捷性,如hashtable,hastmap等,hashcode是用来在散列存储结构中确定对象的存储地址的。 2.如果两个对象相同,就是适用

Java中的数据类型,可分为两类: 1.基本数据类型,它们之间的比较,应用双等号,比较的是它们的值。 2.复合数据类型(类) 当他们用双等号进行比较的时