美文网首页
OracleJDK 7新特性

OracleJDK 7新特性

作者: 烤玉米馒头 | 来源:发表于2018-07-13 19:14 被阅读0次

    0. 好记性不如烂笔头

    工作这些年,没有很好的整理java相关知识点,从今天开始陆续整理。

    1. switch支持使用字符串

    jdk7之前switch语句只能使用Integer及与之兼容的类型做分支判断,比如char,short,byte,和对应的包装类Character,Short,Byte;而jdk7则支持使用字符串,如:

    public class StringSwitch {
    
        public static Integer getCode(String name) {
            Integer code;
            switch (name) {
                case "苹果":
                    code = 1;
                    break;
                case "香蕉":
                    code = 2;
                    break;
    
                default:
                    code = 0;
            }
    
            return code;
        }
    
        public static void main(String[] args){
            System.out.println(getCode("苹果"));
            System.out.println(getCode("香蕉"));
            System.out.println(getCode("梨子"));
        }
    }
    

    这一特性是在编译器层面实现的,我们可以通过IDEA反编译看到,其实编译器使用String的hashCode做为判断条件,再加上String的equals:

    //
    // Source code recreated from a .class file by IntelliJ IDEA
    // (powered by Fernflower decompiler)
    //
    public class StringSwitch {
        public StringSwitch() {
        }
    
        public static Integer getCode(String name) {
            byte var3 = -1;
            switch(name.hashCode()) {
            case 1065923:
                if (name.equals("苹果")) {
                    var3 = 0;
                }
                break;
            case 1253072:
                if (name.equals("香蕉")) {
                    var3 = 1;
                }
            }
    
            Integer code;
            switch(var3) {
            case 0:
                code = 1;
                break;
            case 1:
                code = 2;
                break;
            default:
                code = 0;
            }
    
            return code;
        }
    
        public static void main(String[] args) {
            System.out.println(getCode("苹果"));
            System.out.println(getCode("香蕉"));
            System.out.println(getCode("梨子"));
        }
    }
    
    

    另,代码中的魔法值,应该使用enum来维护。

    2. 数值字面量增强

    jdk7之前紧支持十、十六、八进制,而jdk7增加了二进制的支持,并且允许在数值之前增加下划线“_”分隔,这样便于阅读,注意:不能添加在前后,如果在前面添加下划线,那就会歧义,如:_123表示为数值还是为一变量。

    public class NumericLiteral {
    
        public static void main(String[] args) {
            System.out.println(123_456_789);
            System.out.println(0123_456_7);
            System.out.println(0xa23_456);
            System.out.println(0b100__010_0010);
        }
    }
    
    

    3. 异常处理优化

    3.1 一个catch子句能捕获多个异常

    public class CatchMutiException {
    
        public static void main(String[] args) {
            try {
                System.out.println(1 / 0);
    
            } catch (ArithmeticException | NullPointerException | NumberFormatException ex) {
    //            ex = null; // 会编译错误
                ex.printStackTrace();
            }
        }
    
    }
    

    捕获的异常多余1个时,ex变量就隐式为final的变量,不能再重新赋值。并且多个异常间不能有父子类关系,其实也可以理解,如若为父子类关系,那其实可以去掉子类异常的捕获了。

    3.2 重新抛出异常精准检查

    重新捕获异常时,会检查该异常是否能被抛出,而jdk7之前是不会检查的。
    如下的代码会编译失败,因为从throwException方法的声明不会抛出CloneNotSupportedException 异常,但可能会抛出NumberFormatException,虽然没有声明,这也就是说只会对受检异常做分析,而非受检异常是无法分析出是否会抛出的。

    public class MultiExceptionTypeChecking {
    
        public static void throwException() throws IOException, ClassNotFoundException {
    
        }
    
        public static void main(String[] args) {
            try {
                throwException();
    
            } catch (CloneNotSupportedException | NumberFormatException | IOException | ClassNotFoundException e) {
                e.printStackTrace();
            }
        }
    
    }
    

    3.3 Throwable增加addSuppressed、getSuppressed

    public class ReadFile {
        public void read(String filename) throws IOException {
            FileInputStream input = null;
            IOException readException = null;
            try {
                input = new FileInputStream(filename);
            } catch (IOException ex) {
                readException = ex;
            } finally {
                if (input != null) {
                    try {
                        input.close();
                    } catch (IOException ex) {
                        if (readException != null) {
                            readException.addSuppressed(ex);
                        }
                        else {
                            readException = ex;
                        }
                    }
                }
                if (readException != null) {
                    throw readException;
                }
            }
        }
    }
    

    4. try-catch-resouces

    jdk7之前需要在finally语句对socket、文件、数据库连接等资源关闭,jdk7后,只有继承AutoCloseable接口就能使用try-catch-resouces语句自动关闭。

    public class ResourceBasicUsage {
        public String readFile(String path) throws IOException {
            try (BufferedReader reader = new BufferedReader(new FileReader(path))) {
                StringBuilder builder = new StringBuilder();
                String line = null;
                while ((line = reader.readLine()) != null) {
                    builder.append(line);
                    builder.append(String.format("%n"));
                }
                return builder.toString();
            }
        }
    }
    

    如果使用资源和close都抛异常时,则抛出的是使用资源的异常,并对close的异常addSuppressed;若只有close抛出异常时,则捕获到的是close的异常,这会影响整体的业务受继续执行,所以一般情况,只记录close时的异常,而不抛出,如:

    public class ReadFile {
        public void read(String filename) throws BaseException {
            FileInputStream input = null;
            IOException readException = null;
            try {
                input = new FileInputStream(filename);
            } catch (IOException ex) {
                readException = ex;
            } finally {
                if (input != null) {
                    try {
                        input.close();
                    } catch (IOException ex) {
                        if (readException == null) {
                            ex.printStackTrace(); // 打印异常
                        }else{
                            readException.addSuppressed(ex);
                        }
                    }
                }
                if (readException != null) {
                    throw new BaseException(readException);
                }
            }
        }
    }
    

    5. 泛型初始化语句推测

    Map<String, List<String>> map = new HashMap<>();
    

    相关文章

      网友评论

          本文标题:OracleJDK 7新特性

          本文链接:https://www.haomeiwen.com/subject/pyvouftx.html