Java新特性

来源:互联网 发布:vba的数组查询 编辑:程序博客网 时间:2024/05/17 02:44
Java7新特性
1.运行速度提高了,这个得益于Java7采用的模块化体系.简单的说,在运行的时候,对于虚拟机中不使用到的模块不加载.这样当然读取速度提高了.
2.支持多语言:Rubby Python等,这些扩展都是运行在虚拟机上握.
3.效率:开发提高了.简化了一些编程.另外优化了内存执行效率也提高了.

4.很多期待功能象闭包,当然在其他语言中已经早已实现的东东,在JAVA里究竟会是什么?


“举世瞩目”的java 7近日发布,oracle网站上列出了java 语言的新特性 http://www.oracle.com/technetwork/java/javase/jdk7-relnotes-418459.html,最近出差,晚上闲来无事,将这些java语言的新特性试了下,very cool。
    下面介绍了java 7的一些新特性,翻译自oracle网站,结合自己的实战。对Java 7研究不深,以下内容有对有错,欢迎大家批评指正,共同学习!

    环境: ubuntu 11.04+eclipse 3.8
    本来是用netbeans7.0.1,可是非常难用(不习惯 netBeans),加之用了几天之后,eclipse3.8推出,也支持java7,就切换到了更熟悉的eclipse下。顺便说一句,ubuntu11.04界面做的挺不错的,非常喜欢(附图是win 7下的无缝模式)。

    java 7下载: http://www.oracle.com/technetwork/java/javase/downloads/index.html
    eclipse 3.8下载: http://download.eclipse.org/eclipse/downloads/drops/S-3.8M1-201108031800/
    Netbeans 7.0.1 下载:http://netbeans.org/downloads/start.html?platform=linux&lang=zh_CN&option=javaee


    特性1:二进制字面值(Binary Literals)

    在java7里,整形(byte,short,int,long)类型的值可以用二进制类型来表示了,在使用二进制的值时,需要在前面加上ob或oB,看代码
   
Java代码  收藏代码
  1.        //b 大小写都可以  
  2. int a = 0b01111_00000_11111_00000_10101_01010_10;  
  3. short b = (short)0b01100_00000_11111_0;  
  4. byte c = (byte)0B0000_0001;  
  5.      


    其次,二进制同十进制和十六进制相比,可以一目了然的看出数据间的关系。例如下面这个数组中展示了每次移动一位后数字的变化。
   
Java代码  收藏代码
  1. public static final int[] phases = {  
  2.    0b00110001,  
  3.    0b01100010,  
  4.    0b11000100,  
  5.    0b10001001,  
  6.    0b00010011,  
  7.    0b00100110,  
  8.    0b01001100,  
  9.    0b10011000  
  10. }  

如果用十六进制来表示的,它们之间的关系就无法一眼看出来了。
Java代码  收藏代码
  1. public static final int[] phases = {  
  2.  0x310x620xC40x890x130x260x4C0x98  
  3. }  


    特性2:数字变量对下划线_的支持

    你可以在数值类型的变量里添加下滑线,除了以下的几个地方不能添加:
      数字的开头和结尾
      小数点前后
      F或者L前
      需要出现string类型值的地方(针对用0x或0b表示十六进制和二进制,参考第一点),比如0x101,不能用0_x101
   
Java代码  收藏代码
  1. int num = 1234_5678_9;  
  2. float num2 = 222_33F;  
  3. long num3 = 123_000_111L;  
  4.   
  5. //下面的不行  
  6. //数字开头和结尾  
  7. int nu = _123;  
  8. int nu = 123_;  
  9. //小数点前后  
  10. float f = 123_.12;  
  11. float f = 123._12;  
  12. //F或者L前  
  13. long l = 123_L;  
  14. float f = 123_F;  
  15. //需要出现String的地方  
  16. int num = 0_b123;  
  17. float f = 0_x123F;  


    这个,我个人觉得没什么实际作用,只是可以提升代码的可读性。

    特性3:switch 对String的支持

    这个大家期待很久了,switch终于支持String了
   
Java代码  收藏代码
  1. public static void first() {  
  2.     //项目状态  
  3.     String status = "approval";  
  4.     //我们之前经常根据项目状态不同来进行不同的操作  
  5.     //目前已经换成enum类型  
  6.       
  7.     switch (status) {  
  8.         case "shouli":  
  9.             System.out.println("状态是受理");  
  10.             break;  
  11.         case "approval":  
  12.             System.out.println("状态是审批");  
  13.             break;  
  14.         case "finish":  
  15.             System.out.println("状态是结束");  
  16.             break;  
  17.         default:  
  18.             System.out.println("状态未知");  
  19.     }  
  20. }  


    每个case是使用String的equals方法来进行比较的,对大小写敏感。

    和一连串的if-else-then想比,使用switch来计较String,Java编译器会生成更加有效的字节码,写一个例子测试一下。

Java代码  收藏代码
  1. public static void second() {  
  2.       String status = "approval";  
  3.       if ("shouli".equals(status)) {  
  4.           System.out.println("状态是受理");  
  5.       } else if ("approval".equals(status)) {  
  6.           System.out.println("状态是审批");  
  7.       } else if ("finish".equals(status)) {  
  8.           System.out.println("状态是结束");  
  9.       } else {  
  10.           System.out.println("状态未知");  
  11.       }  
  12. }  

使用javap之后,生成字节码如下:
switch
Java代码  收藏代码
  1. public static void first();  
  2.     Code:  
  3.        0: ldc           #2                  // String approval  
  4.        2: astore_0        
  5.        3: aload_0         
  6.        4: astore_1        
  7.        5: iconst_m1       
  8.        6: istore_2        
  9.        7: aload_1         
  10.        8: invokevirtual #3                  // Method java/lang/String.hashCode:()I  
  11.       11: lookupswitch  { // 3  
  12.            -127444260572  
  13.             -90314605644  
  14.             118524473958  
  15.                default83  
  16.           }  
  17.       44: aload_1         
  18.       45: ldc           #4                  // String shouli  
  19.       47: invokevirtual #5                  // Method java/lang/String.equals:(Ljava/lang/Object;)Z  
  20.       50: ifeq          83  
  21.       53: iconst_0        
  22.       54: istore_2        
  23.       55goto          83  
  24.       58: aload_1         
  25.       59: ldc           #2                  // String approval  
  26.       61: invokevirtual #5                  // Method java/lang/String.equals:(Ljava/lang/Object;)Z  
  27.       64: ifeq          83  
  28.       67: iconst_1        
  29.       68: istore_2        
  30.       69goto          83  
  31.       72: aload_1         
  32.       73: ldc           #6                  // String finish  
  33.       75: invokevirtual #5                  // Method java/lang/String.equals:(Ljava/lang/Object;)Z  
  34.       78: ifeq          83  
  35.       81: iconst_2        
  36.       82: istore_2        
  37.       83: iload_2         
  38.       84: tableswitch   { // 0 to 2  
  39.                      0112  
  40.                      1123  
  41.                      2134  
  42.                default145  
  43.           }  
  44.      112: getstatic     #7                  // Field java/lang/System.out:Ljava/io/PrintStream;  
  45.      115: ldc           #8                    
  46.      117: invokevirtual #9                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V  
  47.      120goto          153  
  48.      123: getstatic     #7                  // Field java/lang/System.out:Ljava/io/PrintStream;  
  49.      126: ldc           #10                   
  50.      128: invokevirtual #9                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V  
  51.      131goto          153  
  52.      134: getstatic     #7                  // Field java/lang/System.out:Ljava/io/PrintStream;  
  53.      137: ldc           #11                   
  54.      139: invokevirtual #9                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V  
  55.      142goto          153  
  56.      145: getstatic     #7                  // Field java/lang/System.out:Ljava/io/PrintStream;  
  57.      148: ldc           #12                  
  58.      150: invokevirtual #9                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V  
  59.      153return    


   用if-else串生成的字节码
  
Java代码  收藏代码
  1.  public static void second();  
  2. de:  
  3.  0: ldc           #2                  // String approval  
  4.  2: astore_0        
  5.  3: ldc           #4                  // String shouli  
  6.  5: aload_0         
  7.  6: invokevirtual #5                  // Method java/lang/String.equals:(Ljava/lang/Object;)Z  
  8.  9: ifeq          23  
  9. 12: getstatic     #7                  // Field java/lang/System.out:Ljava/io/PrintStream;  
  10. 15: ldc           #8                    
  11. 17: invokevirtual #9                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V  
  12. 20goto          71  
  13. 23: ldc           #2                  // String approval  
  14. 25: aload_0         
  15. 26: invokevirtual #5                  // Method java/lang/String.equals:(Ljava/lang/Object;)Z  
  16. 29: ifeq          43  
  17. 32: getstatic     #7                  // Field java/lang/System.out:Ljava/io/PrintStream;  
  18. 35: ldc           #10                   
  19. 37: invokevirtual #9                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V  
  20. 40goto          71  
  21. 43: ldc           #6                  // String finish  
  22. 45: aload_0         
  23. 46: invokevirtual #5                  // Method java/lang/String.equals:(Ljava/lang/Object;)Z  
  24. 49: ifeq          63  
  25. 52: getstatic     #7                  // Field java/lang/System.out:Ljava/io/PrintStream;  
  26. 55: ldc     
  27. 57: invokevirtual #9                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V  
  28. 60goto          71  
  29. 63: getstatic     #7                  // Field java/lang/System.out:Ljava/io/PrintStream;  
  30. 66: ldc           #12                   
  31. 68: invokevirtual #9                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V  
  32. 71return   

   网上说,用switch之后比用if-else生成的字节码更有效一些,不过目前至少从长度上来说,switch还是长一些
  

   特性4:try-with-resources 声明

   try-with-resources 是一个定义了一个或多个资源的try 声明,这个资源是指程序处理完它之后需要关闭它的对象。try-with-resources 确保每一个资源在处理完成后都会被关闭。
可以使用try-with-resources的资源有:
任何实现了java.lang.AutoCloseable 接口和java.io.Closeable 接口的对象。

来看例子:
Java代码  收藏代码
  1.   public static String readFirstLineFromFile(String path) throws IOException {  
  2.      try (BufferedReader br = new BufferedReader(new FileReader(path))) {  
  3.        return br.readLine();  
  4.      }  
  5. }  

   在java 7 以及以后的版本里,BufferedReader实现了java.lang.AutoCloseable接口。
  
Java代码  收藏代码
  1.        try (Closeable obj = new Closeable() {  
  2.        @Override  
  3.        public void close() throws IOException {  
  4.       // do something  
  5.         }  
  6. }) {  
  7. // do something  
  8. }  
  9.   
  10. try (AutoCloseable obj = new AutoCloseable() {  
  11.         @Override  
  12.     public void close() throws IOException {  
  13.        // do something  
  14.     }  
  15. }) {  
  16.        // do something  
  17. }   
  18.     

  
   由于BufferedReader定义在try-with-resources 声明里,无论try语句正常还是异常的结束,它都会自动的关掉。而在java7以前,你需要使用finally块来关掉这个对象。
 
Java代码  收藏代码
  1. public static String readFirstLineFromFileWithFinallyBlock(String path) throws IOException {  
  2.    BufferedReader br = new BufferedReader(new FileReader(path));  
  3.    try {  
  4.       return br.readLine();  
  5.    } finally {  
  6.       if (br != null) br.close();  
  7.    }  
  8.  }  


   然而,如果 readLine() 和 close() 这两个方法都抛出异常,那么readFirstLineFromFileWithFinallyBlock 方法只会抛出后面部分也就是finally块中的内容,try块中的异常就被抑制了,对于我们的程序来说,这显然不是一种好的方式。
   而在java 7中,无论是try块还是try-with-resource中抛出异常,readFirstLineFromFile会捕捉到try块的异常,try-with-resources中中异常被禁止了。在java 7 中,你能捕捉到被禁止的异常。后面会介绍。
 
   另外,一个try-with-resourcse声明了可以包含多个对象的声明,用分号隔开,和声明一个对象相同,会在结束后自动调用close方法,调用顺序和生命顺序相反。
  
Java代码  收藏代码
  1. try (  
  2.   java.util.zip.ZipFile zf = new java.util.zip.ZipFile(zipFileName);  
  3.   java.io.BufferedWriter writer = java.nio.file.Files.newBufferedWriter(outputFilePath, charset)  
  4. ) {  
  5.   // do something  
  6. }  

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


   特性5:捕获多种异常并用改进后的类型检查来重新抛出异常
  
   1、捕获多种异常

   在Java SE7里,一个catch可以捕获多个异常,这样可以减少重复代码。每个异常之间用 | 隔开。
  
Java代码  收藏代码
  1. public static void first(){  
  2.     try {  
  3. BufferedReader reader = new BufferedReader(new FileReader(""));  
  4. Connection con = null;  
  5. Statement stmt = con.createStatement();  
  6.     } catch (IOException | SQLException e) {  
  7. //捕获多个异常,e就是final类型的  
  8. e.printStackTrace();  
  9.     }  
  10. }  

   而在Java SE6以前,需要这样写
  
Java代码  收藏代码
  1.       public static void second() {  
  2.     try {  
  3.         BufferedReader reader = new BufferedReader(new FileReader(""));  
  4.         Connection con = null;  
  5.         Statement stmt = con.createStatement();  
  6.     } catch (IOException e) {  
  7.         e.printStackTrace();  
  8.     } catch (SQLException e) {  
  9.         e.printStackTrace();  
  10.     }  
  11. }  
  12.     

   注意,如果一个catch处理了多个异常,那么这个catch的参数默认就是final的,你不能在catch块里修改它的值。
   另外,用一个catch处理多个异常,比用多个catch每个处理一个异常生成的字节码要更小更高效。

   使用一个catch生成的字节码
  
Java代码  收藏代码
  1.  public static void first();  
  2. Code:  
  3.    0new           #2                  // class java/io/BufferedReader  
  4.    3: dup             
  5.    4new           #3                  // class java/io/FileReader  
  6.    7: dup             
  7.    8: ldc           #4                  // String   
  8.   10: invokespecial #5                  // Method java/io/FileReader."<init>":(Ljava/lang/String;)V  
  9.   13: invokespecial #6                  // Method java/io/BufferedReader."<init>":(Ljava/io/Reader;)V  
  10.   16: astore_0        
  11.   17: aconst_null     
  12.   18: astore_1        
  13.   19: aload_1         
  14.   20: invokeinterface #7,  1            // InterfaceMethod java/sql/Connection.createStatement:()Ljava/sql/Statement;  
  15.   25: astore_2        
  16.   26goto          34  
  17.   29: astore_0        
  18.   30: aload_0         
  19.   31: invokevirtual #10                 // Method java/lang/Exception.printStackTrace:()V  
  20.   34return          
  21. Exception table:  
  22.    from    to  target type  
  23.        0    26    29   Class java/io/IOException  
  24.        0    26    29   Class java/sql/SQLException  


   使用两个catch生成的字节码
  
Java代码  收藏代码
  1.  public static void second();  
  2. Code:  
  3.    0new           #2                  // class java/io/BufferedReader  
  4.    3: dup             
  5.    4new           #3                  // class java/io/FileReader  
  6.    7: dup             
  7.    8: ldc           #4                  // String   
  8.   10: invokespecial #5                  // Method java/io/FileReader."<init>":(Ljava/lang/String;)V  
  9.   13: invokespecial #6                  // Method java/io/BufferedReader."<init>":(Ljava/io/Reader;)V  
  10.   16: astore_0        
  11.   17: aconst_null     
  12.   18: astore_1        
  13.   19: aload_1         
  14.   20: invokeinterface #7,  1            // InterfaceMethod java/sql/Connection.createStatement:()Ljava/sql/Statement;  
  15.   25: astore_2        
  16.   26goto          42  
  17.   29: astore_0        
  18.   30: aload_0         
  19.   31: invokevirtual #11                 // Method java/io/IOException.printStackTrace:()V  
  20.   34goto          42  
  21.   37: astore_0        
  22.   38: aload_0         
  23.   39: invokevirtual #12                 // Method java/sql/SQLException.printStackTrace:()V  
  24.   42return          
  25. Exception table:  
  26.    from    to  target type  
  27.        0    26    29   Class java/io/IOException  
  28.        0    26    37   Class java/sql/SQLException  

  
   switch那里生成的字节码不太明显看出来优化在哪里,这个很明显。首先,字节码长度变少 其次,从最后可以看出,target type都指向29行,两个catch会指向不同的行~

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

   在方法的声明上,使用throws语句时,你可以指定更加详细的异常类型。
  
  
Java代码  收藏代码
  1. static class FirstException extends Exception { }  
  2. static class SecondException extends Exception { }  
  3.   
  4. public void rethrowException(String exceptionName) throws Exception {  
  5.   try {  
  6.      if (exceptionName.equals("First")) {  
  7.          throw new FirstException();  
  8.      } else {  
  9.          throw new SecondException();  
  10.      }  
  11.   } catch (Exception e) {  
  12.    throw e;  
  13.   }  
  14.  }  


   这个例子,try块中只能抛出两种异常,但是因为catch里的类型是 Exception,在java SE7以前的版本中,在方法声明中throws 只能写Exception,但是在java SE7及以后的版本中,可以在throws后面写 FirstException和SecondException——编译器能判断出throw e语句抛出的异常一定来自try块,并且try块只能抛出FirstException和SecondException。
  
Java代码  收藏代码
  1.     public static void reThrowException(String exceptionName)  
  2.         throws FirstException, SecondException{  
  3. try {  
  4.     if ("first".equals(exceptionName))  
  5.     throw new FirstException();  
  6.     else  
  7.     throw new SecondException();  
  8.     } catch (Exception e) {  
  9.     throw e;  
  10.     }  
  11.        }  
  12.     

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

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

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


    特性6:创建泛型对象时类型推断

    只要编译器可以从上下文中推断出类型参数,你就可以用一对空着的尖括号<>来代替泛型参数。这对括号私下被称为菱形(diamond)。

    在Java SE 7之前,你声明泛型对象时要这样
   
Java代码  收藏代码
  1. List<String> list = new ArrayList<String>();  


    而在Java SE7以后,你可以这样
   
Java代码  收藏代码
  1. List<String> list = new ArrayList<>();  

  
     因为编译器可以从前面(List)推断出推断出类型参数,所以后面的ArrayList之后可以不用写泛型参数了,只用一对空着的尖括号就行。当然,你必须带着”菱形”<>,否则会有警告的。
  
     Java SE7 只支持有限的类型推断:只有构造器的参数化类型在上下文中被显著的声明了,你才可以使用类型推断,否则不行。
    
Java代码  收藏代码
  1. List<String> list = new ArrayList<>();  
  2. list.add("A");  
  3.   
  4. //这个不行  
  5. list.addAll(new ArrayList<>());  
  6.   
  7. // 这个可以  
  8. List<? extends String> list2 = new ArrayList<>();  
  9. list.addAll(list2);  


     注意:菱形<>主要用在变量声明里。
 
     类里也可以使用类型推断
    


    准备返京,未完待续~


    Java 7 从呼之欲出到千呼万唤使出来,经历了好几年,期间sun也易主,真是不容易。
   
    不过想要马上大规模的使用还不现实,Java 6从推出到大规模的使用花了两三年的时间吧(这里我不太清楚)甚至更久,到现在还有好多大公司使用 java5或4呢,所以这也是我为什么把java 7装到虚拟机上的缘故,毕竟商业的东西,还是以稳定为主。
    以上介绍了些皮毛,未来还要靠大家自己多多努力,争取两年后,java 7正式商用了,大家也能对java 7掌握的更熟练写,更好的应用,提高自己的工作效率。
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 企业微信公众号中的文章边框怎么办 怎么办我在数学答题卡上画了分割线 游泳的时候泳裙飘起来怎么办 两岁宝宝误服了酵素梅怎么办 人被困在山洞里没有氧气怎么办? 一个人太爱你可你不爱他怎么办 牙齿还没掉又长了新牙齿怎么办 两岁宝宝牙齿发黑烂牙怎么办 怀孕八个月被小孩压到肚子了怎么办 在花场上班客人约我出去玩怎么办 小天才电话手表开不了机怎么办 黑色笔芯弄在白色衣服上怎么办 su文件打开是意外的格式怎么办 su卡的动一下就卡怎么办 犀牛vary渲染的太曝光了怎么办 脑子老是乱想幻想控制不住怎么办 猫抓了破了点皮怎么办 小孩子喜欢玩别人家的玩具怎么办 孩子把别人家的玩具玩坏了怎么办 小新和爸妈一起睡觉那他们怎么办 ps画纸画的时候一直在移动怎么办 宝宝磕碰到家具上鼻梁碰破该怎么办 月经推迟11天了怎么办孕测棒单杠 小孩子不小心把蜡笔吃一点怎么办 线切割切割的工件表面有条纹怎么办 苹果手机不能用流量更新吃鸡怎么办 吃鸡更新成雨林如果内存不够怎么办 绝地求生刺激战场背包满了怎么办 绝地求生刺激战场模拟器满了怎么办 绝地求生刺激战场电脑版满了怎么办 绝地求生手游模拟器注册上限怎么办 绝地求生电脑模拟器已达上限怎么办 三星s5锁屏密码忘了怎么办 字画装框的时候起褶皱怎么办 指甲油抹在手上不在指甲上怎么办 我把油画的布割破了怎么办 胜战本领怎么看、走上战场怎么办 胜战本领怎么看 走上战场怎么办 数码相机拍出的相片亮度太亮怎么办 国考照片错了怎么办招生办能改吗 国考英语准考证名字错了怎么办