jdk7和8的一些新特性介绍

来源:互联网 发布:网络情缘一线牵表情包 编辑:程序博客网 时间:2024/06/15 05:32
本文是我学习了解了jdk7和jdk8的一些新特性的一些资料,有兴趣的大家可以浏览下下面的内容。
官方文档:http://www.oracle.com/technetwork/java/javase/jdk7-relnotes-418459.html
 
在jdk7的新特性方面主要有下面几方面的增强:
 
1.jdk7语法上
 
   1.1二进制变量的表示,支持将整数类型用二进制来表示,用0b开头。
 
   // 所有整数 int, short,long,byte都可以用二进制表示
    // An 8-bit 'byte' value:
    byteaByte = (byte) 0b00100001;
 
    // A 16-bit 'short' value:
    shortaShort = (short) 0b1010000101000101;
 
    // Some 32-bit 'int' values:
    intanInt1 = 0b10100001010001011010000101000101;
    intanInt2 = 0b101;
    intanInt3 = 0B101; // The B can be upper or lower case.
 
    // A 64-bit 'long' value. Note the "L" suffix:
    longaLong = 0b1010000101000101101000010100010110100001010001011010000101000101L;
 
    // 二进制在数组等的使用
    finalint[] phases = { 0b00110001, 0b01100010, 0b11000100, 0b10001001,
    0b00010011, 0b00100110, 0b01001100, 0b10011000 };
 
1.2 Switch语句支持string类型
 
       publicstatic 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:
                 thrownew IllegalArgumentException("Invalid day of the week: " + dayOfWeekArg);
         }
         returntypeOfDay;
    }
 
1.3Try-with-resource语句
   
  注意:实现java.lang.AutoCloseable接口的资源都可以放到try中,跟final里面的关闭资源类似; 按照声明逆序关闭资源 ;Try块抛出的异常通过Throwable.getSuppressed获取
 
    try(java.util.zip.ZipFile zf = newjava.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());
    }
    }
 
1.4Catch多个异常 说明:Catch异常类型为final; 生成Bytecode 会比多个catch小; Rethrow时保持异常类型
 
    publicstatic void main(String[] args) throwsException {
    try{
    testthrows();
    }catch(IOException | SQLException ex) {
    throwex;
    }
    }
    publicstatic void testthrows() throwsIOException, SQLException {
    }
 
1.5数字类型的下划线表示 更友好的表示方式,不过要注意下划线添加的一些标准,可以参考下面的示例
 
    longcreditCardNumber = 1234_5678_9012_3456L;
    longsocialSecurityNumber = 999_99_9999L;
    floatpi = 3.14_15F;
    longhexBytes = 0xFF_EC_DE_5E;
    longhexWords = 0xCAFE_BABE;
    longmaxLong = 0x7fff_ffff_ffff_ffffL;
    bytenybbles = 0b0010_0101;
    longbytes = 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
    intx2 = 5_2;              // OK (decimal literal)
    //int x3 = 52_;              // Invalid; cannot put underscores at the end of a literal
    intx4 = 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
    intx7 = 0x5_2;            // OK (hexadecimal literal)
    //int x8 = 0x52_;            // Invalid; cannot put underscores at the end of a number
    intx9 = 0_52;             // OK (octal literal)
    intx10 = 05_2;            // OK (octal literal)
    //int x11 = 052_;            // Invalid; cannot put underscores at the end of a number
    1.6泛型实例的创建可以通过类型推断来简化 可以去掉后面new部分的泛型类型,只用<>就可以了。
      //使用泛型前
    List strList = newArrayList();
    List<String> strList4 = newArrayList<String>();
    List<Map<String, List<String>>> strList5 =  newArrayList<Map<String, List<String>>>();
 
      
    //编译器使用尖括号 (<>) 推断类型
    List<String> strList0 = newArrayList<String>();
    List<Map<String, List<String>>> strList1 =  newArrayList<Map<String, List<String>>>();
    List<String> strList2 = newArrayList<>();
    List<Map<String, List<String>>> strList3 = newArrayList<>();
    List<String> list = newArrayList<>();
    list.add("A");
      // The following statement should fail since addAll expects
      // Collection<? extends String>
    //list.addAll(new ArrayList<>());
 
1.7在可变参数方法中传递非具体化参数,改进编译警告和错误
 
Heap pollution 指一个变量被指向另外一个不是相同类型的变量。例如
 
    List l = newArrayList<Number>();
    List<String> ls = l;       // unchecked warning
    l.add(0,newInteger(42));// another unchecked warning
    String s = ls.get(0);     // ClassCastException is thrown
    Jdk7:
    publicstatic <T> voidaddToList (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;
 
  1.8信息更丰富的回溯追踪 就是上面trytry语句和里面的语句同时抛出异常时,异常栈的信息
 
    java.io.IOException 
    §?      at Suppress.write(Suppress.java:19
    §?      at Suppress.main(Suppress.java:8
    §?      Suppressed:  java.io.IOException
    §?          at Suppress.close(Suppress.java:24)
    §?          at Suppress.main(Suppress.java:9
    §?      Suppressed:  java.io.IOException
    §?          at  Suppress.close(Suppress.java:24
    §?          at  Suppress.main(Suppress.java:9)
      
 
2. NIO2的一些新特性
     
    1.java.nio.file 和java.nio.file.attribute包 支持更详细属性,比如权限,所有者
    2.  symbolic and hard links支持
    3. Path访问文件系统,Files支持各种文件操作
    4.高效的访问metadata信息
    5.递归查找文件树,文件扩展搜索
    6.文件系统修改通知机制
    7.File类操作API兼容
    8.文件随机访问增强 mapping a region,locl a region,绝对位置读取
    9. AIO Reactor(基于事件)和Proactor
 
  下面列一些示例:
 
2.1IO and New IO 监听文件系统变化通知
 
通过FileSystems.getDefault().newWatchService()获取watchService,然后将需要监听的path目录注册到这个watchservice中,对于这个目录的文件修改,新增,删除等实践可以配置,然后就自动能监听到响应的事件。
 
    privateWatchService watcher;
    publicTestWatcherService(Path path) throwsIOException {
    watcher = FileSystems.getDefault().newWatchService();
    path.register(watcher, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY);
    }
    publicvoid handleEvents() throwsInterruptedException {
    while(true) {
    WatchKey key = watcher.take();
    for(WatchEvent<?> event : key.pollEvents()) {
    WatchEvent.Kind kind = event.kind();
    if(kind == OVERFLOW) {// 事件可能lost or discarded
    continue;
    }
    WatchEvent<Path> e = (WatchEvent<Path>) event;
    Path fileName = e.context();
    System.out.printf("Event %s has happened,which fileName is %s%n",kind.name(), fileName);
    }
    if(!key.reset()) {
    break;
    }
 
2.2IO and New IO遍历文件树 ,通过继承SimpleFileVisitor类,实现事件遍历目录树的操作,然后通过Files.walkFileTree(listDir, opts, Integer.MAX_VALUE, walk);这个API来遍历目录树
 
    privatevoid workFilePath() {
    Path listDir = Paths.get("/tmp");// define the starting file
    ListTree walk = newListTree();
    …Files.walkFileTree(listDir, walk);…
    // 遍历的时候跟踪链接
    EnumSet opts = EnumSet.of(FileVisitOption.FOLLOW_LINKS);
    try{
    Files.walkFileTree(listDir, opts, Integer.MAX_VALUE, walk);
    }catch(IOException e) {
    System.err.println(e);
    }
    classListTree extendsSimpleFileVisitor<Path> {// NIO2 递归遍历文件目录的接口
    @Override
    publicFileVisitResult postVisitDirectory(Path dir, IOException exc) {
    System.out.println("Visited directory: " + dir.toString());
    returnFileVisitResult.CONTINUE;
    }
    @Override
    publicFileVisitResult visitFileFailed(Path file, IOException exc) {
    System.out.println(exc);
    returnFileVisitResult.CONTINUE;
    }
    }
 
 
2.3AIO异步IO 文件和网络 异步IO在java
 NIO2实现了,都是用AsynchronousFileChannel,AsynchronousSocketChanne等实现,关于同步阻塞IO,同步非阻塞IO,异步阻塞IO和异步非阻塞IO在ppt的这页上下面备注有说明,有兴趣的可以深入了解下。Java NIO2中就实现了操作系统的异步非阻塞IO。
 
    // 使用AsynchronousFileChannel.open(path, withOptions(), 
        // taskExecutor))这个API对异步文件IO的处理 
        publicstatic void asyFileChannel2() { 
            finalint THREADS = 5
            ExecutorService taskExecutor = Executors.newFixedThreadPool(THREADS); 
            String encoding = System.getProperty("file.encoding"); 
            List<Future<ByteBuffer>> list = newArrayList<>(); 
            intsheeps = 0
            Path path = Paths.get("/tmp"
                    "store.txt"); 
            try(AsynchronousFileChannel asynchronousFileChannel = AsynchronousFileChannel 
                    .open(path, withOptions(), taskExecutor)) { 
                for(inti = 0; i < 50; i++) { 
                    Callable<ByteBuffer> worker = newCallable<ByteBuffer>() { 
                        @Override 
                        publicByteBuffer call() throwsException { 
                            ByteBuffer buffer = ByteBuffer 
                                    .allocateDirect(ThreadLocalRandom.current() 
                                            .nextInt(100,200)); 
                            asynchronousFileChannel.read(buffer, ThreadLocalRandom 
    ……
 
         
3. JDBC 4.1
 
3.1.可以使用try-with-resources自动关闭Connection, ResultSet, 和 Statement资源对象
 
3.2. RowSet 1.1:引入RowSetFactory接口和RowSetProvider类,可以创建JDBC driver支持的各种 row sets,这里的rowset实现其实就是将sql语句上的一些操作转为方法的操作,封装了一些功能。
 
3.3. JDBC-ODBC驱动会在jdk8中删除
 
    try(Statement stmt = con.createStatement()) {
     RowSetFactory aFactory = RowSetProvider.newFactory();
      CachedRowSet crs = aFactory.createCachedRowSet();
       
     RowSetFactory rsf = RowSetProvider.newFactory("com.sun.rowset.RowSetFactoryImpl",null);
    WebRowSet wrs = rsf.createWebRowSet();
    createCachedRowSet
    createFilteredRowSet
    createJdbcRowSet
    createJoinRowSet
    createWebRowSet
 
 
4. 并发工具增强
 
4.1.fork-join
 最大的增强,充分利用多核特性,将大问题分解成各个子问题,由多个cpu可以同时解决多个子问题,最后合并结果,继承RecursiveTask,实现compute方法,然后调用fork计算,最后用join合并结果。
 
    classFibonacci extendsRecursiveTask<Integer> {
    finalint n;
    Fibonacci(intn) {
    this.n = n;
    }
    privateint compute(intsmall) {
    finalint[] results = { 1,1,2,3,5,8,13,21,34,55,89};
    returnresults[small];
    }
    publicInteger compute() {
    if(n <= 10) {
    returncompute(n);
    }
    Fibonacci f1 = newFibonacci(n - 1);
    Fibonacci f2 = newFibonacci(n - 2);
    System.out.println("fork new thread for " + (n - 1));
    f1.fork();
    System.out.println("fork new thread for " + (n - 2));
    f2.fork();
    returnf1.join() + f2.join();
    }
    }
 
 4.2.ThreadLocalRandon 并发下随机数生成类,保证并发下的随机数生成的线程安全,实际上就是使用threadlocal
 
    finalint MAX = 100000;
    ThreadLocalRandom threadLocalRandom = ThreadLocalRandom.current();
    longstart = System.nanoTime();
    for(inti = 0; i < MAX; i++) {
    threadLocalRandom.nextDouble();
    }
    longend = System.nanoTime() - start;
    System.out.println("use time1 : " + end);
    longstart2 = System.nanoTime();
    for(inti = 0; i < MAX; i++) {
    Math.random();
    }
    longend2 = System.nanoTime() - start2;
    System.out.println("use time2 : " + end2);
 
        
4.3. phaser 类似cyclebarrier和countdownlatch,不过可以动态添加资源减少资源
 
     voidrunTasks(List<Runnable> tasks) {
    finalPhaser phaser = newPhaser(1);// "1" to register self
    // create and start threads
    for(finalRunnable task : tasks) {
    phaser.register();
    newThread() {
    publicvoid run() {
    phaser.arriveAndAwaitAdvance();// await all creation
    task.run();
    }
    }.start();
    }
    // allow threads to start and deregister self
    phaser.arriveAndDeregister();
    }
 
5. Networking增强
 
新增URLClassLoader close方法,可以及时关闭资源,后续重新加载class文件时不会导致资源被占用或者无法释放问题
URLClassLoader.newInstance(newURL[]{}).close();
新增Sockets Direct Protocol
绕过操作系统的数据拷贝,将数据从一台机器的内存数据通过网络直接传输到另外一台机器的内存中
 
6. Multithreaded Custom Class Loaders 
     
    解决并发下加载class可能导致的死锁问题,这个是jdk1.6的一些新版本就解决了,jdk7也做了一些优化。有兴趣可以仔细从官方文档详细了解
 
jdk7前:
   
    Class Hierarchy:           
      classA extendsB
      classC extendsD
    ClassLoader Delegation Hierarchy:
    Custom Classloader CL1:
      directly loads classA
      delegates to custom ClassLoader CL2 forclass B
    Custom Classloader CL2:
      directly loads classC
      delegates to custom ClassLoader CL1 forclass D
    Thread1:
      Use CL1 to load classA (locks CL1)
        defineClass A triggers
          loadClass B (tryto lock CL2)
    Thread2:
      Use CL2 to load classC (locks CL2)
        defineClass C triggers
          loadClass D (tryto lock CL1)
    Synchronization in the ClassLoader classwa
 
jdk7
 
    Thread1:
      Use CL1 to load classA (locks CL1+A)
        defineClass A triggers
          loadClass B (locks CL2+B)
    Thread2:
      Use CL2 to load classC (locks CL2+C)
        defineClass C triggers
          loadClass D (locks CL1+D)
 
 
7. Security 增强
 
    7.1.提供几种 ECC-based algorithms (ECDSA/ECDH) Elliptic Curve Cryptography (ECC)
    7.2.禁用CertPath Algorithm Disabling
    7.3. JSSE (SSL/TLS)的一些增强
 
8. Internationalization 增强 增加了对一些编码的支持和增加了一些显示方面的编码设置等
     
    1. New Scripts and Characters from Unicode 6.0.0
    2. Extensible Support forISO 4217Currency Codes
    Currency类添加:     
           getAvailableCurrencies
           getNumericCode
           getDisplayName
           getDisplayName(Locale)
    3. Category Locale Support
     getDefault(Locale.Category)FORMAT  DISPLAY
    4. Locale Class Supports BCP47 and UTR35
           UNICODE_LOCALE_EXTENSION
           PRIVATE_USE_EXTENSION
           Locale.Builder
           getExtensionKeys()
           getExtension(char)
           getUnicodeLocaleType(String
            ……
    5. New NumericShaper Methods
    NumericShaper.Range
    getShaper(NumericShaper.Range)
    getContextualShaper(Set<NumericShaper.Range>)……
 
 
9.jvm方面的一些特性增强,下面这些特性有些在jdk6中已经存在,这里做了一些优化和增强。
 
1.Jvm支持非java的语言 invokedynamic 指令
 
2. Garbage-First Collector 适合server端,多处理器下大内存,将heap分成大小相等的多个区域,mark阶段检测每个区域的存活对象,compress阶段将存活对象最小的先做回收,这样会腾出很多空闲区域,这样并发回收其他区域就能减少停止时间,提高吞吐量。
 
3. HotSpot性能增强
    Tiered Compilation  -XX:+UseTieredCompilation 多层编译,对于经常调用的代码会直接编译程本地代码,提高效率
   Compressed Oops  压缩对象指针,减少空间使用
  Zero-Based Compressed Ordinary Object Pointers (oops) 进一步优化零基压缩对象指针,进一步压缩空间
 
4. Escape Analysis  逃逸分析,对于只是在一个方法使用的一些变量,可以直接将对象分配到栈上,方法执行完自动释放内存,而不用通过栈的对象引用引用堆中的对象,那么对于对象的回收可能不是那么及时。
 
5. NUMA Collector Enhancements 
 
NUMA(Non Uniform Memory Access),NUMA在多种计算机系统中都得到实现,简而言之,就是将内存分段访问,类似于硬盘的RAID,Oracle中的分簇
 
10. Java 2D Enhancements
 
    1. XRender-Based Rendering Pipeline -Dsun.java2d.xrender=True
    2. Support forOpenType/CFF Fonts GraphicsEnvironment.getAvailableFontFamilyNames
    3. TextLayout Support forTibetan Script
    4. Support forLinux Fonts
 
11. Swing Enhancements
 
    1.  JLayer
    2.  Nimbus Look & Feel
    3.  Heavyweight and Lightweight Components
    4.  Shaped and Translucent Windows
    5.  Hue-Saturation-Luminance (HSL) Color Selection in JColorChooser Class
 
 
 
12. Jdk8 lambda表达式 最大的新增的特性,不过在很多动态语言中都已经原生支持。
 
原来这么写:
 
    btn.setOnAction(newEventHandler<ActionEvent>() {
        @Override
        publicvoid handle(ActionEvent event) {
            System.out.println("Hello World!");
        }
    });
        
jdk8直接可以这么写:
 
    btn.setOnAction(
        event -> System.out.println("Hello World!")
    );  
        
更多示例:
    
    publicclass Utils {
        publicstatic int compareByLength(String in, String out){
            returnin.length() - out.length();
        }
    }
 
    publicclass MyClass {
        publicvoid doSomething() {
            String[] args = newString[] {"microsoft","apple","linux","oracle"}
            Arrays.sort(args, Utils::compareByLength);
        
    
 
13.jdk8的一些其他特性,当然jdk8的增强功能还有很多,大家可以参考http://openjdk.java.net/projects/jdk8/
 
用Metaspace代替PermGen
动态扩展,可以设置最大值,限制于本地内存的大小
Parallel array sorting 新APIArrays#parallelSort.
 
    New Date & Time API
    Clock clock = Clock.systemUTC(); //return the current time based on your system clock and set to UTC.
 
    Clock clock = Clock.systemDefaultZone(); //return time based on system clock zone
 
    longtime = clock.millis(); //time in milliseconds from January 1st, 1970
原创粉丝点击