Java1.7新特性
1.switch语句支持字符串变量
public String getTypeOfDayWithSwitchStatement(String dayOfWeekArg) {
     String typeOfDay;
     switch (dayOfWeekArg) {
         case "Monday":
             typeOfDay = "Start of work week";
             break;
         case "Tuesday":
         case "Wednesday":
         case "Thursday":
             typeOfDay = "Midweek";
             break;
         case "Friday":
             typeOfDay = "End of work week";
             break;
         case "Saturday":
         case "Sunday":
             typeOfDay = "Weekend";
             break;
         default:
             throw new IllegalArgumentException("Invalid day of the week: " + dayOfWeekArg);
     }
     return typeOfDay;
}
switch 语句比较表达式中的String对象和每个case标签关联的表达式,就好像它是在使用String.equals方法一样;因此,switch语句中 String对象的比较是大小写敏感的。相比于链式的if-then-else语句,Java编译器通常会从使用String对象的switch语句中生成更高效的字节码。
2.泛型实例化类型自动推断
以下两个语句等价:
ArrayList<String> al1 = new ArrayList<String>(); // Old
ArrayList<String> al2 = new ArrayList<>(); // New
3. 新的整数字面表达方式 - "0b"前缀和"_"连数符
a. 表示二进制字面值的前缀0b。
比如以下三个变量的值相同:
byte b1 = 0b00100001; // New
byte b2 = 0x21; // Old
byte b3 = 33; // Old
b. 字面常量数字的下划线。用下划线连接整数提升其可读性,自身无含义,不可用在数字的起始和末尾。
Java编码语言对给数值型的字面值加下划线有严格的规定。如上所述,你只能在数字之间用下划线。你不能用把一个数字用下划线开头,或者已下划线结尾。这里有一些其它的不能在数值型字面值上用下划线的地方:
- 在数字的开始或结尾
 - 对浮点型数字的小数点附件
 - F或L下标的前面
 - 该数值型字面值是字符串类型的时候
 
float pi1 = 3_.1415F; // 无效的; 不能在小数点之前有下划线
float pi2 = 3._1415F; // 无效的; 不能在小数点之后有下划线
long socialSecurityNumber1=999_99_9999_L;//无效的,不能在L下标之前加下划线
int a1 = _52; // 这是一个下划线开头的标识符,不是个数字
int a2 = 5_2; // 有效
int a3 = 52_; // 无效的,不能以下划线结尾
int a4 = 5_______2; // 有效的
int a5 = 0_x52; // 无效,不能在0x之间有下划线
int a6 = 0x_52; // 无效的,不能在数字开头有下划线
int a7 = 0x5_2; // 有效的 (16进制数字)
int a8 = 0x52_; // 无效的,不能以下划线结尾
int a9 = 0_52; // 有效的(8进制数)
int a10 = 05_2; // 有效的(8进制数)
int a11 = 052_; // 无效的,不能以下划线结尾
4.在单个catch代码块中捕获多个异常,以及用升级版的类型检查重新抛出异常
在Java 7中,catch代码块得到了升级,用以在单个catch块中处理多个异常。如果你要捕获多个异常并且它们包含相似的代码,使用这一特性将会减少代码重复度。下面用一个例子来理解。
Java 7之前的版本:
catch (IOException ex) {
    logger.error(ex);
    throw new MyException(ex.getMessage());
catch (SQLException ex) {
    logger.error(ex);
    throw new MyException(ex.getMessage());
}catch (Exception ex) {
    logger.error(ex);
    throw new MyException(ex.getMessage());
}
在Java 7中,我们可以用一个catch块捕获所有这些异常:
catch(IOException | SQLException | Exception ex){
    logger.error(ex);
    throw new MyException(ex.getMessage());
}
如果用一个catch块处理多个异常,可以用管道符(|)将它们分开,在这种情况下异常参数变量(ex)是定义为final的,所以不能被修改。这一特性将生成更少的字节码并减少代码冗余。
另一个升级是编译器对重新抛出异常(rethrown exceptions)的处理。这一特性允许在一个方法声明的throws从句中指定更多特定的异常类型。
与以前版本相比,Java SE 7 的编译器能够对再次抛出的异常(rethrown exception)做出更精确的分析。这使得你可以在一个方法声明的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语句块可能会抛出FirstException或者SecondException类型的异常。设想一下,你想在rethrowException方法声明的throws从句中指定这些异常类型。在Java SE 7之前的版本,你无法做到。因为在catch子句中的异常参数e是java.lang.Exception类型的,catch子句对外抛出异常参数e,你只能在rethrowException方法声明的throws从句中指定抛出的异常类型为java.lang.Exception (或其父类java.lang.Throwable)。
不过,在Java SE 7中,你可以在rethrowException方法声明的throws从句中指定抛出的异常类型为FirstException和SecondException。Java SE 7的编译器能够判定这个被throw语句抛出的异常参数e肯定是来自于try子句,而try子句只会抛出FirstException或SecondException类型的异常。尽管catch子句的异常参数e是java.lang.Exception类型,但是编译器可以判断出它是FirstException或SecondException类型的一个实例:
public class Java7MultipleExceptions {
    public static void main(String[] args) {
        try{
            rethrow("abc");
        }catch(FirstException | SecondException | ThirdException e){
            //以下赋值将会在编译期抛出异常,因为e是final型的
            //e = new Exception();
            System.out.println(e.getMessage());
        }
    }
    static void rethrow(String s) throws FirstException, SecondException, ThirdException {
        try {
            if (s.equals("First"))
                throw new FirstException("First");
            else if (s.equals("Second"))
                throw new SecondException("Second");
            else
                throw new ThirdException("Third");
        } catch (Exception e) {
            //下面的赋值没有启用重新抛出异常的类型检查功能,这是Java 7的新特性
            // e=new ThirdException();
            throw e;
        }
    }
    static class FirstException extends Exception {
        public FirstException(String msg) {
            super(msg);
        }
    }
    static class SecondException extends Exception {
        public SecondException(String msg) {
            super(msg);
        }
    }
    static class ThirdException extends Exception {
        public ThirdException(String msg) {
            super(msg);
        }
    }
}
不过,如果catch捕获的异常变量在catch子句中被重新赋值,那么异常类型检查的分析将不会启用,因此在这种情况下,你不得不在方法声明的throws从句中指定异常类型为java.lang.Exception。
更具体地说,从Java SE 7开始,当你在单个catch子句中声明一种或多种类型的异常,并且重新抛出这些被捕获的异常时,需符合下列条件,编译器才会对再次抛出的异常进行类型验证:
- try子句会抛出该异常。
 - 在此之前,没有其他的catch子句捕获该异常。
 - 该异常类型是catch子句捕获的多个异常中的一个异常类型的父类或子类。
 
5.try-with-resources语句
try-with-resources语句是一个声明一个或多个资源的try语句。一个资源作为一个对象,必须在程序结束之后关闭。try-with-resources语句确保在语句的最后每个资源都被关闭,任何实现了Java.lang.AutoCloseable和java.io.Closeable的对象都可以使用try-with-resource来实现异常处理和关闭资源。
下面通过对比来体会这个新特性。
JDK1.7之前:
/**
* JDK1.7之前我们必须在finally块中手动关闭资源,否则会导致资源的泄露
* @author Liao
*
*/
public class PreJDK7 { public static String readFirstLingFromFile(String path) throws IOException {
BufferedReader br = null; try {
br = new BufferedReader(new FileReader(path));
return br.readLine();
} catch (IOException e) {
e.printStackTrace();
} finally {//必须在这里关闭资源
if (br != null)
br.close();
}
return null;
}
}
JDK1.7及以后版本
/**
* JDK1.7之后就可以使用try-with-resources,不需要
* 我们在finally块中手动关闭资源
* @author Liao
*/
public class AboveJDK7 { static String readFirstLineFromFile(String path) throws IOException { try (BufferedReader br = new BufferedReader(new FileReader(path))) {
return br.readLine();
}
}
}
通过上面的对比,try-with-resources的优点
代码精炼,在JDK1.7之前都有finally块(这时可能会有一个问题,1.7后的finally将何去何从,还有用处吗?当然有用了,try-with-resources只是帮助我们避免了资源关闭的重复工作,但它并没有代替finally的作用啊,所以1.7后finally仍然是用来处理一定会被执行的代码块,不过这个功能使用场景不是很大。),如果使用一些扩建可能会将finally块交由框架处理,如spring。JDK及以后的版本只要资源类实现了AutoCloseable或Closeable程序在执行完try块后会自动close所使用的资源无论br.readLine()是否抛出异常,我估计针对JDK1.7像Spring这些框架也会做出一些比较大的调整。
代码更完全。在出现资源泄漏的程序中,很多情况是开发人员没有或者开发人员没有正确的关闭资源所导致的。JDK1.7之后采用try-with-resources的方式,则可以将资源关闭这种与业务实现没有很大直接关系的工作交给JVM完成,省去了部分开发中可能出现的代码风险。
异常抛出顺序
在JDK1.7之前如果rd.readLine()与rd.close()都抛出异常则只会抛出finally块中的异常,不会抛出rd.readLine()中的异常,这样经常会导致得到的异常信息不是调用程序想要得到的。
在JDK1.7及以后采用了try-with-resource机制,如果在try-with-resource声明中抛出异常(如文件无法打开或无法关闭)的同时rd.readLine()也抛出异常,则只会抛出rd.readLine()的异常。
try-with-resource可以声明多个资源(声明语句之间分号分割,最后一个可忽略分号)。下面的例子是在一个ZIP文件中检索文件名并将检索后的文件存入一个txt文件中。
JDK1.7及以上版本:
public class AboveJDK7_2 {  
    public static void writeToFileZipFileContents(String zipFileName,String outputFileName) throws java.io.IOException {  
        java.nio.charset.Charset charset = java.nio.charset.Charset.forName("US-ASCII");  
        java.nio.file.Path outputFilePath = java.nio.file.Paths.get(outputFileName);  
        //打开zip文件,创建输出流
        try (
                java.util.zip.ZipFile zf = new java.util.zip.ZipFile(zipFileName);  
                java.io.BufferedWriter writer = java.nio.file.Files.newBufferedWriter(outputFilePath, charset)
            )   
            {//遍历文件写入txt
                for (java.util.Enumeration entries = zf.entries(); entries.hasMoreElements();) {  
                        String newLine = System.getProperty("line.separator");  
                        String zipEntryName = ((java.util.zip.ZipEntry) entries.nextElement()).getName() + newLine;
                        writer.write(zipEntryName, 0, zipEntryName.length());
                }
            }
    }
}
注:上面的例子,无论正常执行还是有异常抛出,zf和write都会被执行close()方法,不过需要注意的是在JVM里调用的顺序是与生命的顺序相反。在JVM中调用的顺讯为:
writer.close();
zf.close();
所以在使用时一定要注意资源关闭的顺序。
转自:http://www.jianshu.com/p/5ae0cb34622e
Java1.7新特性的更多相关文章
- java1.8新特性之stream流式算法
		
在Java1.8之前还没有stream流式算法的时候,我们要是在一个放有多个User对象的list集合中,将每个User对象的主键ID取出,组合成一个新的集合,首先想到的肯定是遍历,如下: List& ...
 - Stream:java1.8新特性
		
原 Stream:java1.8新特性 2017年08月01日 18:15:43 kekeair-zhang 阅读数:392 标签: streamjava1-8新特性 更多 个人分类: 日记 版权声明 ...
 - java1.8新特性(一)
		
一直在更新java 版本,原来也没有关注java版本的变化 引入的一些新的api 引起注意的还是 关于一些并发包的使用,那时候才对每个版本的特性 去了解了一下,虽然 不一定都用上了,但是不管学习什 ...
 - java1.7新特性:try-with-resources
		
转载:https://blog.csdn.net/fanxiaobin577328725/article/details/53067163 首先看代码: import org.junit.Test; ...
 - Java1.8新特性——接口改动和Lambda表达式
		
Java1.8新特性——接口改动和Lambda表达式 摘要:本文主要学习了Java1.8的新特性中有关接口和Lambda表达式的部分. 部分内容来自以下博客: https://www.cnblogs. ...
 - java1.8新特性整理(全)
		
版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/yitian_66/article/deta ...
 - Java1.8新特性 - Stream流式算法
		
一. 流式处理简介 在我接触到java8流式数据处理的时候,我的第一感觉是流式处理让集合操作变得简洁了许多,通常我们需要多行代码才能完成的操作,借助于流式处理可以在一行中实现.比如我们希望对一个包 ...
 - java1.8新特性
		
转自:http://www.oschina.NET/translate/everything-about-Java-8 建议去看原文,此处转载只是为了记录. 这篇文章是对Java8中即将到来的改进做一 ...
 - java1.8新特性(三 关于 ::的用法)
		
java1.8 推出了一种::的语法 用法 身边 基本没人用1.8的新API 目前 我也是只处于学习 运用 阶段 有点 知其然不知其所以然 通过后面的学习,及时查漏补缺 一个类中 有 静态方法 ,非静 ...
 
随机推荐
- 禁止百度转码和百度快照缓存的META声明
			
今天手机 site 中国博客联盟时,发现网被转码了,虽然这个网站没做移动站,但是我也不希望被百度转码,因为这相当于拦截了所有来自手机的流量.下面说一下禁止百度转码和禁止百度快照缓存的方法. 一.禁止百 ...
 - wireshark开发环境搭建
			
自己完成了wireshark开发环境的搭建,主要参考资料是wireshark的官方developer-guide.pdf,网址:https://www.wireshark.org/docs/. 现把搭 ...
 - Kendo UI 简单使用
			
1 准备工作 引入JS文件和CSS文件 <link href="js/kendoui/styles/kendo.common.min.css" rel="style ...
 - eclipse使用STS插件 报错:SocketTimeoutException: Read timed out
			
新建boot项目后,提示: SocketTimeoutException: Read timed out 解决: 在eclipse.ini末尾,追加: -Djava.net.preferIPv4Sta ...
 - 傻瓜式Spring教学第二课
			
什么是依赖注入 先说什么是依赖 如下: class A{ B b; } class B{ } 则称A依赖B. 依赖:A的某些业务逻辑需要B的参与,如果不对A中的参数b进行实例化,那么A中的某些业务逻辑 ...
 - SpringBoot中使用Servlet
			
1.在入口Application类上加入注解@ServletComponentScan @SpringBootApplication @ServletComponentScan public clas ...
 - CSS 样式分类
			
CSS样式可以分为三大类:内联样式.内部样式表和外部样式表 1.内联样式(样式写在html标签里,只对该标签的内容起作用) <span style="color:red;font-si ...
 - nodejs的异步非阻塞IO
			
简单表述一下:发启向系统IO操作请求,系统使用线程池IO操作,执行完放到事件队列里,node主线程轮询事件队列,读取结果与调用回调.所以说node并非真的单线程,还是使用了线程池的多线程. 上个图看看 ...
 - 【3dsMax安装失败,如何卸载、安装3dMax 2019?】
			
AUTODESK系列软件着实令人头疼,安装失败之后不能完全卸载!!!(比如maya,cad,3dsmax等).有时手动删除注册表重装之后还是会出现各种问题,每个版本的C++Runtime和.NET f ...
 - [转] js 实现table每列可左右拖动改变列宽度
			
<!DOCTYPE HTML> <html> <head> <meta charset="gbk"> <tit ...