一起学Java7新功能扩展 - 深入历险分享

jopen 12年前

一:java7语言扩展的简介

20117月,在时隔数年之后,java的一个重大版本javase7发布了。在这个新的版本中,java平台新增了很多的新的特性。在java虚拟机方面,invokedynamic指令的加入使虚拟机上的动态语言的性能得到了很大的提升。这使得开发人员可以享受到动态语言带来的在提高生产效率方面的好处。在java语言方面,语言本身的进一步简化,使开发人员编写代码的效率更高。在java类库方面,新的IO库和同步实现工具类为开发人员提供了更多的实现功能。从另外一个角度来说,javase7oracle公司领导力的顾虑。Javase7的发布也证明了jcpopenjdk的社区驱动模式可以很好地推动java向前发展。

         随着新版本的发布,肯定会有越来越多的开发人员想尝试使用javase7中的新特性,毕竟开发者社区对这个新版本的期待了太长的时间。在java程序中使用这些新特性,可以提高代码质量,提升工作效率。Java平台的每个版本都致力于提高java程序的运行性能。同时随着新版本的发布,企业都应该考虑把java程序的运行平台升级到最新的javase7,这样可以享受到性能提升所带来的好处。对于新的java程序开发,推荐使用javase7作为标准的运行平台。

         在介绍具体的新特性之前,有必要介绍一下coin项目。OpenJDK中的Coin项目的目的是维护对java语言所做的语法增强。在Coin项目开始之初,曾经广泛地向社区征求提议。在短短一个月时间内就收到了近70条提议。最后有9条提议被列入考虑之中。在这9条提议中,有6条成为java7的一部分,剩下的6提议会在java8中重新考虑,还有1条提议被移到其他项目中实现。这6条被接纳的提议除了switch语句中使用字符串、数值字面的改进、优化的异常处理、try-with-resources语句和优化变长参数的方法调用之外还有简化泛型类创建的“<>”操作符。在java8中考虑2条提议则分别是集合类字面量和为ListMap提供类似数组的按序号的访问方式。

         和其他对java平台所做的修改一样,Coin项目所建议的修改也需要通过JCP来完成。这些改动以JSR334(Small Enhancements to the Java)

         二:java7 switch特性介绍

今天首先来让我们看看耳熟能详的switch是如何被提升扩展对字符串的支持的!大家都知道在java7之前switch语句中的条件表达式的类型只能是与整数类型兼容的类型,包括基本类型charbyteshortint,与这些基本类型对应的封装类型CharacterByteShortInteger,还有枚举类型。这样的限制降低了语言的灵活性,使开发人员在需要根据其他类型的表达式来进行条件选择时,不得不增加额外的代码来绕过这个限制。为此java7放宽了这个限制,额外增加了一种可以在switch语句中使用的表达式类型,那就是很常见的字符串,即String类型

         三:java7switch用法

                   在基本java7的代码中使用这个新特性非常简单,因为这个新特性并没有改变switch的语法含义,只是多了一种开发人员可以选择的条件判断的数据类型。但是这个简单的新特性却带来了重大的影响,因为根据字符串进行条件判断在开发中是很常见的。

                   下面来看看java7中根据字符串进行条件判断【Test】:

 

public class Test {           public String getTitle(String name,String sex){                       String title ="";                       switch(sex){                                case "男":                                         title=name+"\t it man";                                         break;                                case "女":                                         title=name+"\t it woman";                                         break;                                default:                                         title=name+"变形金刚";                       }                       return title;             }             public static void main(String[] args) {                       System.out.println(new Test().getTitle("Dobby", "男"));             }    }

 

运行结果:一起学Java7新功能扩展——深入历险分享

    PS:switch语句中,表达式的值是不能是null,否则会在运行时抛出NullPointerException,case子句中也不能使用null,否则会出现编译错误。

         看到这里或许你觉得这个没什么嘛就是一个简单的switch,你别着急接下来就是switch的深度历险了,让我们看看他是如何实现switch接受String类型的!根据switch语句的语法要求,其case子句的值是不能重复的,这个要求对字符串类型的条件表达式同样适用。不过对于字符串来说这种重复值的检查还有一个特殊之处,就是java代码中的字符串可以包含Unicode转义字符。重复值的检查是在java编译器对java源码进行相关的语法转换之后才进行的。这个语法转换过程中包括了对Unicode转义字符的处理。也就是说,有些case子句的值虽然在源码中看起来是不同的,但是经过转换后是一样的,这个就会造成编译错误。

修改上面的代码再执行看看如下修改(使用jdk自带的native2ascii.exe将“女”转换成Unicode)

public String getTitle(String name,String sex){    String title ="";    switch(sex){     case "男":      title=name+"\t it man";      break;     case "\u7537":      title=name+"\t it woman";                                  break;     default:      title=name+"变形金刚";    }        return title;   }

当我们再次编译的时候就会不通过,报出标签重复错误!

一起学Java7新功能扩展——深入历险分享

这是因为其中的switch语句中的两个case子句所使用的值“男”和“\u7537”在经过转义之后变成一样的。“\u7537”是“男”的Unicode转义字符形式。

.java7 switch实现原理

         说了这么多下面让我们来看看switch究竟是如何实现的呢!实际上,这个新特性是在编译器这个层次上实现的。而在java虚拟机和字节码这个层次上,还是只支持在switch语句中使用与整数类型兼容的类型。这么做的目的是为了减少这个特性所影响的范围,以降低实现的代价。在编译器层次实现的含义是,虽然开发人员在java源码的switch语句中使用了字符串类型,但是编译的过程中,编译器会根据源代码的含义来进行转换,将字符串类型转换成与整数兼容的格式。不同的java编译器可能采用不同的方式来完成这个转换,并采用不同的优化策略。比如:如果switch子句中只包含一个case子句,那么可以简单的将其转换成一个if语句。如果switch语句中包含一个case子句和一个default子句,那么可以将其转换成if-else语句。而对于最复杂的情况,只不过使用字符串的哈希值作为switch语句的表达式的值。

         为了验证刚刚的理论同时我们也探究OpenJDK中的java编译器使用的是什么样的转换方式,需要一个名为JAD的工具,这个工具可以把javaclass文件反编译成java源码,下面我们使用JAD把刚刚的Test.class文件反编译。在对编译生成Test类的class文件使用了JAD之后,所得到的内容如下:

一起学Java7新功能扩展——深入历险分享

从上面的代码中可以看出,原来用在switch语句中的字符串被替换成了对应的哈希值,而case子句的值也被替换成原来字符串常用的哈希值。经过这样的转换,java虚拟机所看到的仍然是与整数类型兼容的类型。在这里值得注意的是,在case子句对应的语句块中仍然需要使用Stringequals方法来进行字符串比较。这是因为哈希函数在映射的时候可能存在冲突,多个字符串的哈希值可能是一样的。进行字符串比较是为了保证转换之后的代码逻辑与之前完全一样!

         好了今日历险到此,java7里面的变革还是很大的这里就先分享一则!后面基本分为有以下方面:

1.      语法新特性:对数值字面量的改进、优化的异常处理、try-with-resources语句、优化变长参数的方法调用、

2.      Java语言的动态性:脚本语言支持API、反射API、动态代理、动态语言支持、

3.      Java7其他重要更新:关系数据库访问、javalang包更新、java实用工具类、JavaBeans组件

4.      超越java7lambda表达式、java平台模块化、javaSe8的其他更新

 

    想必大家机子上一定更新到 java7 了吧!只是没有几个人用过吧!接下来就是自己动手历险的时候了!实践是检验真理的唯一标准!(如果没有的自己可以到 oracle 官方下载 java7 jdk )这里透露一下哦, eclipse 最新版也已经集成了 java7 可以到官方下载,不过默认的还是 6 的版本,自己创建项目的时候可以选择,如果发现可以 jre 没有集成, 自己可以添加 java7 jre eclipse 就可以使用了!好了初试 java7 到此结束!后面慢慢在学习!

转自:http://my.oschina.net/BeyondBit/blog/76268