美文网首页java基础
JDK1.7和JDK1.8新特性总结

JDK1.7和JDK1.8新特性总结

作者: 浅蓝色的麻吉 | 来源:发表于2018-10-17 16:11 被阅读992次

    简单总结一下JDK1.7和1.8的新特性,总体上点到为止,想深入的话还需继续深究其中的原理。

    JDK1.7

    1. 二进制变量的表示,支持将整数类型用二进制来表示

    所有整数int、short、long、byte都可以用二进制表示,表示的方法就是在二进制数字前面加上0b

      byte  num1 = 0b00001001;  //1个字节8位
      short num2 =  0b0010000101000101; //2个字节16位
      int   num3 =  0b10100001010001011010000101000101;; //4个字节32位
      long  num4 = 0b0010000101000101101000010100010110100001010001011010000101000101L;//8个字节64位
    
            System.out.println(num1);
            System.out.println(num2);
            System.out.println(num3);
            System.out.println(num4);
    

    输出结果:
    9
    8517
    -1589272251
    2397499697075167557

    2.Switch语句支持String类型。

    在1.6的版本switch的参数中只支持byte、short、char、int、long以及他们的包装类(自动拆箱和自动装箱的支持下),然后在jdk1.7支持了String作为参数。

     String str = "1";
          switch (str){
              case "1":
                  System.out.println("NO.1");
                  break;
              case "2":
                  System.out.println("NO.2");
                  break;
              case "3":
                  System.out.println("NO.3");
                  break;
                  default:
                      System.out.println("fail");
          }
    

    输出结果:
    NO.1

    3. Try-with-resource语句

    • 实现java.long.AutoCloseable接口的资源都可以放到try中
    • 跟final里面的关闭资源类似;
    • 按照声明逆序关闭资源;
    • Try块抛出的异常Throwable.getSuppressed获取。
    • 如果try代码块和try-with-resources语句同时抛出异常,这个方法将会最终抛出try代码块里面的异常,try-with-resources语句里面抛出的异常被压抑了。
    public static void writeToFileZipFileContents(String zipFileName,
                                              String outputFileName)
                                              throws java.io.IOException {
    
        java.nio.charset.Charset charset =
            java.nio.charset.StandardCharsets.US_ASCII;
        java.nio.file.Path outputFilePath =
            java.nio.file.Paths.get(outputFileName);
    
        // Open zip file and create output file with
        // try-with-resources statement
    
        try (
            java.util.zip.ZipFile zf =
                new java.util.zip.ZipFile(zipFileName);
            java.io.BufferedWriter writer =
                java.nio.file.Files.newBufferedWriter(outputFilePath, charset)
        ) {
            // Enumerate each entry
            for (java.util.Enumeration entries =
                                    zf.entries(); entries.hasMoreElements();) {
                // Get the entry name and write it to the output file
                String newLine = System.getProperty("line.separator");
                String zipEntryName =
                    ((java.util.zip.ZipEntry)entries.nextElement()).getName() +
                    newLine;
                writer.write(zipEntryName, 0, zipEntryName.length());
            }
        }
    }
    

    在这个例子中,try-with-resources语句包含了两个用分号隔开的声明:ZipFile和BufferedWriter。当代码块中代码终止,不管是正常还是异常,BufferedWriter和ZipFile对象的close方法都会自动按声明的相反顺序调用。


    下面的例子用try-with-resources语句自动关闭一个java.sql.Statement对象:

    public static void viewTable(Connection con) throws SQLException {
    
        String query = "select COF_NAME, SUP_ID, PRICE, SALES, TOTAL from COFFEES";
    
        try (Statement stmt = con.createStatement()) {
            ResultSet rs = stmt.executeQuery(query);
    
            while (rs.next()) {
                String coffeeName = rs.getString("COF_NAME");
                int supplierID = rs.getInt("SUP_ID");
                float price = rs.getFloat("PRICE");
                int sales = rs.getInt("SALES");
                int total = rs.getInt("TOTAL");
    
                System.out.println(coffeeName + ", " + supplierID + ", " +
                                  price + ", " + sales + ", " + total);
            }
        } catch (SQLException e) {
            JDBCTutorialUtilities.printSQLException(e);
        }
    }
    

    4.Catch支持多个异常

    public static void main(String[] args) throws Exception {
            try {
            testthrows();
            } catch (IOException | SQLException ex) {
            throw ex;
                }
            }
        public static void testthrows() throws IOException, SQLException {
        }
    

    5.数字类型的下划线表示 更友好的表示方式

    不过要注意下划线添加的一些标准,下划线不允许出现在开头和结尾。

    long creditCardNumber = 1234_5678_9012_3456L;
        long socialSecurityNumber = 999_99_9999L;
        float pi = 3.14_15F;
        long hexBytes = 0xFF_EC_DE_5E;
        long hexWords = 0xCAFE_BABE;
        long maxLong = 0x7fff_ffff_ffff_ffffL;
        byte nybbles = 0b0010_0101;
        long bytes = 0b11010010_01101001_10010100_10010010; 
        //float pi1 = 3_.1415F;      // Invalid; cannot put underscores adjacent to a decimal point
        //float pi2 = 3._1415F;      // Invalid; cannot put underscores adjacent to a decimal point
        //long socialSecurityNumber1= 999_99_9999_L;         // Invalid; cannot put underscores prior to an L suffix 
        //int x1 = _52;              // This is an identifier, not a numeric literal
        int x2 = 5_2;              // OK (decimal literal)
        //int x3 = 52_;              // Invalid; cannot put underscores at the end of a literal
        int x4 = 5_______2;        // OK (decimal literal) 
        //int x5 = 0_x52;            // Invalid; cannot put underscores in the 0x radix prefix
        //int x6 = 0x_52;            // Invalid; cannot put underscores at the beginning of a number
        int x7 = 0x5_2;            // OK (hexadecimal literal)
        //int x8 = 0x52_;            // Invalid; cannot put underscores at the end of a number 
        int x9 = 0_52;             // OK (octal literal)
        int x10 = 05_2;            // OK (octal literal)
        //int x11 = 052_;            // Invalid; cannot put underscores at the end of a number 
    

    6.泛型实例的创建可以通过类型推断来简化

    可以去掉后面new部分的泛型类型,只用<>就可以了。


    新特性之前:

        List strList = new ArrayList(); 
        List<String> strList = new ArrayList<String>(); 
        List<Map<String, List<String>>> strList5 =  new ArrayList<Map<String, List<String>>>();
    

    新特性:

        List<String> strList2 = new ArrayList<>(); 
        List<Map<String, List<String>>> strList3 = new ArrayList<>();
        List<String> list = new ArrayList<>();
    

    7.在可变参数方法中传递非具体化参数,改进编译警告和错误

    Heap pollution 指一个变量被指向另外一个不是相同类型的变量。例如

        List l = new ArrayList<Number>();
        List<String> ls = l;       // unchecked warning
        l.add(0, new Integer(42)); // another unchecked warning
        String s = ls.get(0);      // ClassCastException is thrown
        Jdk7:
        public static <T> void addToList (List<T> listArg, T... elements) {
        for (T x : elements) {
        listArg.add(x);
        }
        }
    

    你会得到一个warning
    warning: [varargs] Possible heap pollution from parameterized vararg type
    要消除警告,可以有三种方式
    1.加 annotation @SafeVarargs
    2.加 annotation @SuppressWarnings({"unchecked", "varargs"})
    3.使用编译器参数 –Xlint:varargs;

    JDK8的新特性

    JDK8新特性

    1.接口内允许非抽象方法

    Java 8允许我们给接口添加一个非抽象的方法实现,只需要使用 default关键字即可,这个特征又叫做扩展方法。

    public interface JDK8Interface {  
      
        // static修饰符定义静态方法  
        static void staticMethod() {  
            System.out.println("接口中的静态方法");  
        }  
      
        // default修饰符定义默认方法  
        default void defaultMethod() {  
            System.out.println("接口中的默认方法");  
        }  
    }
    

    2. Lambda 表达式

    λ表达式有三部分组成:参数列表,箭头(->),以及一个表达式或语句块。
    (x, y) -> { return x + y; } ;

    List<String> names = Arrays.asList("peter", "anna", "mike", "xenia");
     
    Collections.sort(names, new Comparator<String>() {
        @Override
        public int compare(String a, String b) {
            return b.compareTo(a);
        }
    });
    
    

    在Java 8 中你就没必要使用这种传统的匿名对象的方式了,Java 8提供了更简洁的语法,lambda表达式:

    Collections.sort(names, (String a, String b) -> {
          return b.compareTo(a);
    });
    
    

    //或者是这样写,可以直接省略掉大括号{}和return关键字。

    Collections.sort(names, (a, b) -> b.compareTo(a));
    

    为什么lambda表示式可以这样随意的使用?
    lambda表达式是如何和java系统的类型进行对应的?每个lambda表达式都对应一个指定的类型,这个指定的类型是由接口确定的。

    功能性接口,它必须且恰好只包含一个抽象方法声明。被指定接口类型所对应的lambda表达式刚好和这个接口的抽象方法想匹配。因为默认方法不是抽象的,因此你可以在你的功能性接口中添加多个默认方法。

    我们可以将任意的接口用作lambda表示式,只要该接口仅仅包含一个抽象方法。为了确保你定义的接口达到要求,你可以在接口上添加@FunctionInterface注解。编译器可以检测到该注解并判断你的接口是否满足条件,如果 你定义的接口包含多个抽象方法时,编译器便会报错

    例如:下面就是一个功能性接口

    @FunctionalInterface
    interface Converter<F, T> {
        T convert(F from);
    }
    

    进行lambda表示式使用:

    Converter<String, Integer> converter = (from) -> Integer.valueOf(from);
    Integer converted = converter.convert("123");
    System.out.println(converted);    // 123
    

    3.方法与构造函数引用

    Java 8 允许你使用 :: 关键字来传递方法或者构造函数引用,上面的代码展示了如何引用一个静态方法,我们也可以引用一个对象的方法.

    前部分的示例在使用静态方法引用的情况下可以被进一步的简化:

    Converter<String, Integer> converter = Integer::valueOf;
    Integer converted = converter.convert("123");
    System.out.println(converted);   // 123
    

    java8可以让你通过关键字::来传递方法和构造函数的引用。上面的示例展示了如何引用一个静态方法。我们同样也可以引用对象方法。

    class Something {
        String startsWith(String s) {
            return String.valueOf(s.charAt(0));
        }
    }
    
    Something something = new Something();
    Converter<String, String> converter = something::startsWith;
    String converted = converter.convert("Java");
    System.out.println(converted);    // "J"
    
    

    现在我们将看到关键字::如何为构造函数工作。首先我们定义一个拥有不同构造函数的bean类:

    class Person {
        String firstName;
        String lastName;
     
        Person() {}
     
        Person(String firstName, String lastName) {
            this.firstName = firstName;
            this.lastName = lastName;
        }
    }
    

    接下来我们定义一个用来创建类person的工厂接口:

    interface PersonFactory<P extends Person> {
        P create(String firstName, String lastName);
    }
    

    不使用通常的手动实现工厂类,我们通过使用构造函数将所有的工作联合在一起:

    PersonFactory<Person> personFactory = Person::new;
    Person person = personFactory.create("Peter", "Parker");
    

    JDK8新特性详细使用教程参考

    JDK8新特性详细使用教程参考

    相关文章

      网友评论

        本文标题:JDK1.7和JDK1.8新特性总结

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