天天看点

jdk新特性研究

1.switch中可以使用字串了

String s = "test";

switch (s) {

case "test" :

     System.out.println("test");

case "test1" :

    System.out.println("test1");

    break ;

default :

    System.out.println("break");

    break ;

}

2.运用List<String> tempList = new ArrayList<>(); 即泛型实例化类型自动推断

3.语法上支持集合,而不一定是数组

 final List<Integer> piDigits = [ 1,2,3,4,5,8 ];

4.新增一些取环境信息的工具方法

 File System.getJavaIoTempDir() // IO临时文件夹

 File System.getJavaHomeDir() // JRE的安装目录

 File System.getUserHomeDir() // 当前用户目录

 File System.getUserDir() // 启动java进程时所在的目录5

5.Boolean类型反转,空指针安全,参与位运算

 Boolean Booleans.negate(Boolean booleanObj)

 True => False , False => True, Null => Null

 boolean Booleans.and(boolean[] array)

 boolean Booleans.or(boolean[] array)

 boolean Booleans.xor(boolean[] array)

 boolean Booleans.and(Boolean[] array)

 boolean Booleans.or(Boolean[] array)

 boolean Booleans.xor(Boolean[] array)

6.两个char间的equals

 boolean Character.equalsIgnoreCase(char ch1, char ch2)

7.安全的加减乘除

 int Math.safeToInt(long value)

 int Math.safeNegate(int value)

 long Math.safeSubtract(long value1, int value2)

 long Math.safeSubtract(long value1, long value2)

 int Math.safeMultiply(int value1, int value2)

 long Math.safeMultiply(long value1, int value2)

 long Math.safeMultiply(long value1, long value2)

 long Math.safeNegate(long value)

 int Math.safeAdd(int value1, int value2)

 long Math.safeAdd(long value1, int value2)

 long Math.safeAdd(long value1, long value2)

 int Math.safeSubtract(int value1, int value2)

8.map集合支持并发请求,且可以写成 Map map = {name:"xxx",age:18};

9.对Java集合(Collections)的增强支持

在JDK1.7之前的版本中,Java集合容器中存取元素的形式如下:

以List、Set、Map集合容器为例:

在JDK1.7中,摒弃了Java集合接口的实现类,如:ArrayList、HashSet和HashMap。而是直接采用[]、{}的形式存入对象,采用[]的形式按照索引、键值来获取集合中的对象,如下:

10.数值可加下划线

例如:int one_million = 1_000_000;

11.支持二进制文字

例如:int binary = 0b1001_1001;

12.简化了可变参数方法的调用

当程序员试图使用一个不可具体化的可变参数并调用一个*varargs* (可变)方法时,编辑器会生成一个“非安全操作”的警告。 

13.自动资源管理

14. try-with-resources 声明

  try-with-resources 是一个定义了一个或多个资源的try 声明,这个资源是指程序处理完它之后需要关闭它的对象。try-with-resources 确保每一个资源在处理完成后都会被关闭。

可以使用try-with-resources的资源有:

任何实现了java.lang.AutoCloseable 接口和java.io.Closeable 接口的对象。

来看例子:

public static String readFirstLineFromFile(String path) throws IOException {  

     try (BufferedReader br = new BufferedReader(new FileReader(path))) {  

       return br.readLine();  

     }  

}  

   在java 7 以及以后的版本里,BufferedReader实现了java.lang.AutoCloseable接口。

   由于BufferedReader定义在try-with-resources 声明里,无论try语句正常还是异常的结束,

   它都会自动的关掉。而在java7以前,你需要使用finally块来关掉这个对象。

public static String readFirstLineFromFileWithFinallyBlock(String path) throws IOException {  

   BufferedReader br = new BufferedReader(new FileReader(path));  

   try {  

      return br.readLine();  

   } finally {  

      if (br != null) br.close();  

   }  

 }  

  然而,如果 readLine() 和 close() 这两个方法都抛出异常,那么readFirstLineFromFileWithFinallyBlock 方法只会抛出后面部分也就是finally块中的内容,try块中的异常就被抑制了,对于我们的程序来说,这显然不是一种好的方式。

  而在java 7中,无论是try块还是try-with-resource中抛出异常,都能捕捉到。

另外,一个try-with-resourcse声明了可以包含多个对象的声明,用分号隔开,和声明一个对象相同,会在结束后自动调用close方法,调用顺序和生命顺序相反。

try (

  java.util.zip.ZipFile zf = new java.util.zip.ZipFile(zipFileName);

  java.io.BufferedWriter writer = java.nio.file.Files.newBufferedWriter(outputFilePath, charset)

) {

// do something

}

此外,try-with-resources 可以跟catch和finally,catch和finally的是在try-with-resources里声明的对象关闭之后才执行的。

15.捕获多种异常并用改进后的类型检查来重新抛出异常

  1、捕获多种异常

在Java SE7里,一个catch可以捕获多个异常,这样可以减少重复代码。每个异常之间用 | 隔开。

public static void first(){  

 try {  

  BufferedReader reader = new BufferedReader(new FileReader(""));  

  Connection con = null;  

  Statement stmt = con.createStatement();  

 } catch (IOException | SQLException e) {  

   //捕获多个异常,e就是final类型的  

   e.printStackTrace();  

    }  

}  

   而在Java SE6以前,需要这样写

   Java代码 

      public static void second() {  

  try {  

    BufferedReader reader = new BufferedReader(new FileReader(""));  

    Connection con = null;  

    Statement stmt = con.createStatement();  

  } catch (IOException e) {  

        e.printStackTrace();  

    } catch (SQLException e) {  

        e.printStackTrace();  

    }  

}  

   注意,如果一个catch处理了多个异常,那么这个catch的参数默认就是final的,你不能在catch块里修改它的值。

另外,用一个catch处理多个异常,比用多个catch每个处理一个异常生成的字节码要更小更高效。

2、用更包容性的类型检查来重新抛出异常

在方法的声明上,使用throws语句时,你可以指定更加详细的异常类型。

static class FirstException extends Exception { }  

static class SecondException extends Exception { }  

public void rethrowException(String exceptionName) throws Exception {  

  try {  

     if (exceptionName.equals("First")) {  

         throw new FirstException();  

     } else {  

         throw new SecondException();  

     }  

  } catch (Exception e) {  

   throw e;  

  }  

 }  

这个例子,try块中只能抛出两种异常,但是因为catch里的类型是 Exception,在java SE7以前的版本中,在方法声明中throws 只能写Exception,但是在java SE7及以后的版本中,可以在throws后面写 FirstException和SecondException——编译器能判断出throw e语句抛出的异常一定来自try块,并且try块只能抛出FirstException和SecondException。

public static void reThrowException(String exceptionName) throws FirstException, SecondException{  

 try {  

    if ("first".equals(exceptionName))  

       throw new FirstException();  

    else  

       throw new SecondException();  

 } catch (Exception e) {  

       throw e;  

 }  

}  

所以尽管catch里的异常类型是Exception,编译器仍然能够知道它是FirstException和 SecondException的实例。怎么样,编译器变得更智能了吧。

但是,如果在catch里对异常重新赋值了,在方法的throws后无法再象上面那样写成FirstException和SecondException了,而需要写成 Exception。

具体来说,在Java SE 7及以后版本中,当你在catch语句里声明了一个或多个异常类型,并且在catch块里重新抛出了这些异常,编译器根据下面几个条件来去核实异常的类型:

- Try块里抛出它

- 前面没有catch块处理它

- 它是catch里一个异常类型的父类或子类。

在开源java工具包里,最有名的当属apache commons。其中,以commons lang包最为开发者熟知。

但是它作为第三方包存在,或多或少给开发者带来一些不便利。

面包牛奶总是会有的,从java7开始,lang包中的一些优秀工具方法,将被正式引入JDK。

下面是各个已确定被引入的工具类或方法说明。

1. 新增类 java.util.Objects (JDK对工具类的命名一向是以s结尾,例如Collections, Arrays)

A, 空指针安全的 equals, hashCode, toString, defaultNull 方法。

即入参传入NULL,工具方法不会抛空指针异常。

调用方法举例:

Boolean result = Objects.equals(obj1, obj2);

B, 比较对象的大小(需要实现Comparable)。

T Objects.max(T comparable1, T comparable2)

T Objects.min(T comparable1, T comparable2)

2. 系统工具类新增一些取环境信息的工具方法。 (java.lang.System)

以往,你需要通过 System.getProperties(”user.dir”) 这样来取。现在只需要调用一下工具方法就可以了。

File System.getJavaIoTempDir() // IO临时文件夹

File System.getJavaHomeDir() // JRE的安装目录

File System.getUserHomeDir() // 当前用户目录

File System.getUserDir() // 启动java进程时所在的目录

3. 包装类型安全转换到原始类型的工具方法。

boolean Boolean.booleanValue(Boolean obj, boolean defaultValue)

char Character.charValue(Character obj, char defaultValue)

byte Byte.byteValue(Byte obj)

byte Byte.byteValue(Byte obj, byte defaultValue)

short Short.shortValue(Short obj)

short Short.shortValue(Short obj, short defaultValue)

int Integer.intValue(Integer obj)

int Integer.intValue(Integer obj, int defaultValue)

long Long.longValue(Long obj)

long Long.longValue(Long obj, long defaultValue)

float Float.floatValue(Float obj)

float Float.floatValue(Float obj, float defaultValue)

double Double.doubleValue(Double obj)

double Double.doubleValue(Double obj, double defaultValue)

4. 针对包装类型的Boolean,提供了更具可读性和空指针安全的工具方法。

boolean Booleans.isTrue(Boolean booleanObj)

boolean Booleans.isFalse(Boolean booleanObj)

boolean Booleans.isNotTrue(Boolean booleanObj)

boolean Booleans.isNotFalse(Boolean booleanObj)

5. Boolean类型反转,空指针安全

Boolean Booleans.negate(Boolean booleanObj)

True => False , False => True, Null => Null

6. Boolean参与位运算

boolean Booleans.and(boolean[] array)

boolean Booleans.or(boolean[] array)

boolean Booleans.xor(boolean[] array)

boolean Booleans.and(Boolean[] array)

boolean Booleans.or(Boolean[] array)

boolean Booleans.xor(Boolean[] array)

7. 两个char间的equals

boolean Character.equalsIgnoreCase(char ch1, char ch2)

8. 声明一批空数组常量,各种类型

Boolean[] Boolean.EMPTY_ARRAY

boolean[] Boolean.EMPTY_PRIMITIVE_ARRAY

Character[] Character.EMPTY_ARRAY

char[] Character.EMPTY_PRIMITIVE_ARRAY

Byte[] Byte.EMPTY_ARRAY

byte[] Byte.EMPTY_PRIMITIVE_ARRAY

Short[] Short.EMPTY_ARRAY

short[] Short.EMPTY_PRIMITIVE_ARRAY

Integer[] Integer.EMPTY_ARRAY

int[] Integer.EMPTY_PRIMITIVE_ARRAY

Long[] Long.EMPTY_ARRAY

long[] Long.EMPTY_PRIMITIVE_ARRAY

Float[] Float.EMPTY_ARRAY

float[] Float.EMPTY_PRIMITIVE_ARRAY

Double[] Double.EMPTY_ARRAY

double[] Double.EMPTY_PRIMITIVE_ARRAY

String[] String.EMPTY_ARRAY

Class[] Class.EMPTY_ARRAY

Object[] Objects.EMPTY_OBJECT_ARRAY

甚至通过Class类型来取空数组。

Boolean.class.emptyArray();

9. 数组长度判定工具类,空指针安全

boolean Arrays.isEmpty(Object[] array)

int Arrays.size(Object[] array)

10. 集合长度判定工具类,空指针安全

boolean Collections.isEmpty(Collection coll)

int Collections.size(Collection coll)

boolean Collections.isEmpty(Map map)

int Collections.size(Map map)

11. 空指针安全的ClassName获取

String Class.getName(Class cls)

String Class.getSimpleName(Class cls)

String Class.getPackageName(Class cls)

12. 可以直接解析locale信息字符串的工具方法

Locale parse(String localeStr)

13. 提供根据语言取国家列表或根据国家取语言列表的工具方法

List Locale.countriesByLanguage(String langaugeStr)

List Locale.languagesByCountry(String countryStr)

14. 安全的加减乘除

int Math.safeToInt(long value)

int Math.safeNegate(int value)

long Math.safeNegate(long value)

int Math.safeAdd(int value1, int value2)

long Math.safeAdd(long value1, int value2)

long Math.safeAdd(long value1, long value2)

int Math.safeSubtract(int value1, int value2)

long Math.safeSubtract(long value1, int value2)

long Math.safeSubtract(long value1, long value2)

int Math.safeMultiply(int value1, int value2)

long Math.safeMultiply(long value1, int value2)

long Math.safeMultiply(long value1, long value2)

JDK1.7的新特性:

首先是模块化特性:现在的 Java7也是采用了模块的划分方式来提速,一些不是必须的模块并没有下载和安装,因此在使用全新的Java7的虚拟机的时候会发现真的很快,当虚拟机需要用到某些功能的时候,再下载和启用相应的模块,这样使得最初需要下载的虚拟机大小得到了有效的控制。同时对启动速度也有了很大的改善。如果你对 OpenJDK的架构比较熟悉,你甚至可以定制JDK的模块。

其次是多语言支持:这里的多语言不是指中文英文之类的语言,而是说Java7的虚拟机对多种动态程序语言增加了支持,比如:Rubby、 Python等等。对这些动态语言的支持极大地扩展了Java虚拟机的能力。对于那些熟悉这些动态语言的程序员而言,在使用Java虚拟机的过程中同样可以使用它们熟悉的语言进行功能的编写,而这些语言是跑在功能强大的JVM之上的。

再有是开发者的开发效率得到了改善:Java7通过多种特性来增强开发效率。比如对语言本身做了一些细小的改变来简化程序的编写,在多线程并发与控制方面:轻量级的分离与合并框架,一个支持并发访问的HashMap等等。通过注解增强程序的静态检查。提供了一些新的API用于文件系统的访问、异步的输入输出操作、Socket通道的配置与绑定、多点数据包的传送等等。

最后是执行效率的提高,也是给人感觉最真切体验的特性:压缩了64位的对象指针,Java7通过对对象指针由 64位压缩到与32位指针相匹配的技术使得内存和内存带块的消耗得到了很大的降低因而提高了执行效率。此外还提供了新的垃圾回收机制(G1)来降低垃圾回收的负载和增强垃圾回收的效果。G1垃圾回收机制拥有更低的暂停率和更好的可预测性。