文档章节

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

Beyond-Bit
 Beyond-Bit
发布于 2012/09/03 00:22
字数 2715
阅读 4228
收藏 53

    特此声明:因网友疑问,这里声明一个重要的安全,就是大家所知的java惊现0day漏洞!8月30日,Oralce紧急发布了新版本的JDK和JRE,原因是发现了一个严重的0day漏洞CVE-2012-4681,远程攻击者可以通过它绕开SecurityManager的限制执行代码!国内的Freebuf在分析恶意代码时发现了其中有这样一段代码,即“我有一只小毛驴,从来也不骑”。

String k1 = "woyouyizhixiaomaol"; String k2 = "conglaiyebuqi"; 

如果对该漏洞感兴趣的童鞋请点击(http://www.freebuf.com/vuls/5485.html国内、http://www.deependresearch.org/2012/08/java-7-vulnerability-analysis.html这个为国外分析)该漏洞一般针对的是applet,国内很少有这样的应用了!(即使有估计也没有几个人挖空心思搞你一个个人电脑!没意义!信息盗卖已经不是新闻了!)国外似乎还有!建议在浏览器中使用Java的同学立刻将自己的Java升级到7u7或6u35版本



一: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", "男"));

         }

}

 

运行结果:

    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;
	}

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


这是因为其中的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之后,所得到的内容如下:


从上面的代码中可以看出,原来用在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 到此结束!后面慢慢在学习!

© 著作权归作者所有

Beyond-Bit

Beyond-Bit

粉丝 44
博文 2
码字总数 3048
作品 0
虹口
架构师
私信 提问
加载中

评论(26)

obaniu
obaniu
C#对switch语句的优化
http://blog.csdn.net/gu_fan/article/details/821049
来历不明
来历不明
这还不够,应该支持object
Beyond-Bit
Beyond-Bit 博主

引用来自“chengArthur”的评论

支持java啊,

大家都很支持!
Beyond-Bit
Beyond-Bit 博主

引用来自“Railgun”的评论

这么做,肯定会有一大堆人用字符串代替枚举了,于是字符串满天飞的大字符串时代来临了!

恩恩!这个倒不一定!大家都有自己的编码习惯!提供这个特性只是一种方式!具体实际使用还是看个人而言!
Railgun
Railgun
这么做,肯定会有一大堆人用字符串代替枚举了,于是字符串满天飞的大字符串时代来临了!
chengArthur
chengArthur
支持java啊,
Beyond-Bit
Beyond-Bit 博主

引用来自“Credo”的评论

java的时间还是没修改吗?

java7已经修复了!这是国外报道“8月中旬Oracle刚刚发布了Java 7u6和6u34版本,但短短半个月时间之后的8月30日,Oralce紧急发布了新版本的JDK和JRE,原因是发现了一个严重的0day漏洞CVE-2012-4681,远程攻击者可以通过它绕开SecurityManager的限制执行代码,但服务器端和桌面端的Java程序不受该漏洞影响。“
Credo-Zhao
Credo-Zhao
java的时间还是没修改吗?
Beyond-Bit
Beyond-Bit 博主

引用来自“yxtwang”的评论

还不如直接学习scala呢?

这个只有选择适合自己的语言来学习!语言本身并不矛盾!
Beyond-Bit
Beyond-Bit 博主

引用来自“LinkerLin”的评论

Java的特性还算是比较稳健的.

恩恩额,每次都是经过严格审核才会加入的!在不影响其他类库的情况下扩展很不错了!!
我的友情链接

拓远教育 岳雷的微软网络课堂 快乐分享 李晨光原创技术博客 老男孩linux运维 7159900 浩子的▁运维笔录ヽ 吟—技术交流 大角牛 Linux SA John IT----你---我---他--- 东妮学IT 高安定的51CTO...

_诺千金
2017/11/22
0
0
和lock一起学beego 博客系统开发为例(三)

mongodb: MongoDB(二):基础知识 Django学习笔记:为Model添加Action 和lock一起学beego 博客系统开发为例(三) 深入Go语言 - 1 django captcha imagintft: 关于captcha使用The _imagingft C ...

d_watson
2016/06/16
18
0
我的友情链接

51CTO博客开发 聆听未来 老男孩的linux博客 卓越始于足下 李晨光原创技术博客 王春海的博客 斩月 For The Dream 改变从现在开始 小崔的成长之路 丁丁历险 sunsky 吟—技术交流 itnihao的运维...

woshiyu001
2017/11/22
0
0
大数据技术学习路线指南:大数据的内幕

这是在真正开始学习大数据之前对大数据的一个概览。为的是让我们成为大数据的主人。 大数据运行机制这是对大数据运行机制的概览,如果你阅读过上一篇(OODA),就会感觉非常熟悉。不错,他们...

qq_41842579
2018/03/29
0
0
博客两万字阶段性总结

不知不觉在简书写博客已经有两万多字了,这应该是我写作字数最多的博客了,就连我自己搭建的GitHub.io博客也比这少一篇博客(因为我到现在都没找到少的是哪一篇。。。),做一个阶段性总结吧...

月见樽
2017/11/28
0
0

没有更多内容

加载失败,请刷新页面

加载更多

抽象同步队列AQS——AbstractQueuedSynchronizer锁详解

AQS——锁的底层支持 谈到并发,不得不谈ReentrantLock;而谈到ReentrantLock,不得不谈AbstractQueuedSynchronizer(AQS)! 类如其名,抽象的队列式的同步器,AQS定义了一套多线程访问共享资...

须臾之余
今天
3
0
springboot配置百度UEditor 富文本详解

富文本简介 UEditor是由百度web前端研发部开发所见即所得富文本web编辑器,具有轻量,可定制,注重用户体验等特点,开源基于MIT协议,允许自由使用和修改代码... 准备工作 ueditor需要单独文...

wotrd
昨天
4
0
mysql 5.7之my.cnf配置大全

[client]port = 3306socket = /tmp/mysql.sock[mysqld]###############################基础设置######################################Mysql服务的唯一编号 每个mysql服务...

Online_Reus
昨天
3
0
MAVEN打包时引入外部链接的包

1.项目引入了ORACLE的jar包,MAVEN配置如下 2.打jar包的时候需要指定下main入口函数mainClass <dependency> <groupId>com.oracle</groupId> <artifactId>ojdbc6</artifactId> ......

Cobbage
昨天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部