007-jdk1.6版本新特性
一、JDK1.6
名称:Mustang(野马)
发布日期:2006-04
新特性:
1.1、AWT新增加了两个类:Desktop和SystemTray【忽略】
前者可以用来打开系统默认浏览器浏览指定的URL,打开系统默认邮件客户端给指定的邮箱发邮件,用默认应用程序打开或编辑文件(比如,用记事本打开以txt为后缀名的文件),用系统默认的打印机打印文档;后者可以用来在系统托盘区创建一个托盘程序.
1.2、AXB是Java Architecture for XML Binding的缩写,可以将一个Java对象转变成为XML格式,反之亦然。
把对象与关系数据库之间的映射称为ORM, 其实也可以把对象与XML之间的映射称为OXM(Object XML Mapping). 原来JAXB是Java EE的一部分,在JDK6中,SUN将其放到了Java SE中,这也是SUN的一贯做法。JDK6中自带的这个JAXB版本是2.0, 比起1.0(JSR 31)来,JAXB2(JSR 222)用JDK5的新特性Annotation来标识要作绑定的类和属性等,这就极大简化了开发的工作量。
1.3、StAX(JSR 173)是JDK6.0中除了DOM和SAX之外的又一种处理XML文档的API。
StAX是The Streaming API for XML的缩写,一种利用拉模式解析(pull-parsing)XML文档的API.StAX通过提供一种基于事件迭代器(Iterator)的API让 程序员去控制xml文档解析过程,程序遍历这个事件迭代器去处理每一个解析事件,解析事件可以看做是程序拉出来的,也就是程序促使解析器产生一个解析事件 然后处理该事件,之后又促使解析器产生下一个解析事件,如此循环直到碰到文档结束符;
SAX也是基于事件处理xml文档,但却 是用推模式解析,解析器解析完整个xml文档后,才产生解析事件,然后推给程序去处理这些事件;DOM 采用的方式是将整个xml文档映射到一颗内存树,这样就可以很容易地得到父节点和子结点以及兄弟节点的数据,但如果文档很大,将会严重影响性能。
4、用JDK6 的Compiler API(JSR 199)去动态编译Java源文件
Compiler API结合反射功能就可以实现动态的产生Java代码并编译执行这些代码,有点动态语言的特征。这 个特性对于某些需要用到动态编译的应用程序相当有用, 比如JSP Web Server,当我们手动修改JSP后,是不希望需要重启Web Server才可以看到效果的,这时候我们就可以用Compiler API来实现动态编译JSP文件,当然,现在的JSP Web Server也是支持JSP热部署的,现在的JSP Web Server通过在运行期间通过Runtime.exec或ProcessBuilder来调用javac来编译代码,这种方式需要我们产生另一个进程去 做编译工作,不够优雅而且容易使代码依赖与特定的操作系统;Compiler API通过一套易用的标准的API提供了更加丰富的方式去做动态编译,而且是跨平台的。
5、轻量级Http Server API:
JDK6 提供了一个简单的Http Server API,据此我们可以构建自己的嵌入式Http Server,它支持Http和Https协议,提供了HTTP1.1的部分实现,没有被实现的那部分可以通过扩展已有的Http Server API来实现,程序员必须自己实现HttpHandler接口,HttpServer会调用HttpHandler实现类的回调方法来处理客户端请求,在 这里,我们把一个Http请求和它的响应称为一个交换,包装成HttpExchange类,HttpServer负责将HttpExchange传给 HttpHandler实现类的回调方法.
6.插入式注解处理API(Pluggable Annotation Processing API)
插入式注解处理API(JSR 269)提供一套标准API来处理Annotations(JSR 175)
实际上JSR 269不仅仅用来处理Annotation,更强大的功能是它建立了Java 语言本身的一个模型,它把method, package, constructor, type, variable, enum, annotation等Java语言元素映射为Types和Elements, 从而将Java语言的语义映射成为对象, 可以在javax.lang.model包下面可以看到这些类. 所以可以利用JSR 269提供的API来构建一个功能丰富的元编程(metaprogramming)环境.
Pluggable Annotation Processing API的核心是Annotation Processor即注解处理器,一般需要继承抽象类javax.annotation.processing.AbstractProcessor
。注意,与运行时注解RetentionPolicy.RUNTIME
不同,注解处理器只会处理编译期注解,也就是RetentionPolicy.SOURCE
的注解类型,处理的阶段位于Java代码编译期间。
6.1、插件化注解处理API的使用步骤大概如下:
- 1、自定义一个Annotation Processor,需要继承
javax.annotation.processing.AbstractProcessor
,并覆写process方法。 - 2、自定义一个注解,注解的元注解需要指定
@Retention(RetentionPolicy.SOURCE)
。 - 3、需要在声明的自定义Annotation Processor中使用
javax.annotation.processing.SupportedAnnotationTypes
指定在第2步创建的注解类型的名称(注意需要全类名,"包名.注解类型名称",否则会不生效)。 - 4、需要在声明的自定义Annotation Processor中使用
javax.annotation.processing.SupportedSourceVersion
指定编译版本。 - 5、可选操作,可以通在声明的自定义Annotation Processor中使用
javax.annotation.processing.SupportedOptions
指定编译参数。
7、用Console开发控制台程序
public static void main(String[] args) { Scanner in = new Scanner(System.in); //git first input System.out.println("plase input your first name:"); in.nextLine(); //git second name System.out.println("please input your second name :"); in.nextLine(); //git age System.out.println("please input your age"); in.nextInt(); }
8、对脚本语言的支持如: ruby, groovy, javascript.
JDK6增加了对脚本语言的支持(JSR 223),原理上是将脚本语言编译成bytecode,这样脚本语言也能享用Java平台的诸多优势,包括可移植性,安全等,另外,由于现在是编译成bytecode后再执行,所以比原来边解释边执行效率要高很多。加入对脚本语言的支持后,对Java语言也提供了以下好处。
1、许多脚本语言都有动态特性,比如,你不需要用一个变量之前先声明它,你可以用一个变量存放完全不同类型的对象,你不需要做强制类型转换,因为转换都是自动的。现在Java语言也可以通过对脚本语言的支持间接获得这种灵活性。
2、 可以用脚本语言快速开发产品原型,因为现在可以Edit-Run,而无需Edit-Compile-Run,当然,因为Java有非常好的IDE支持,我 们完全可以在IDE里面编辑源文件,然后点击运行(隐含编译),以此达到快速开发原型的目的,所以这点好处基本上可以忽略。
3、通过引入脚本语言可以轻松实现Java应用程序的扩展和自定义,我们可以把原来分布在在Java应用程序中的配置逻辑,数学表达式和业务规则提取出来,转用JavaScript来处理。
Sun的JDK6实现包含了一个基于Mozilla Rhino的 脚本语言引擎,支持JavaScript,这并不是说明JDK6只支持JavaScript,任何第三方都可以自己实现一个JSR-223兼容的脚本引擎 使得JDK6支持别的脚本语言,比如,你想让JDK6支持Ruby,那你可以自己按照JSR 223的规范实现一个Ruby的脚本引擎类,具体一点,你需要实现javax.script.ScriptEngine(简单起见,可以继承javax.script.AbstractScriptEngine)和javax.script.ScriptEngineFactory两个接口。当然,在你实现自己的脚本语言引擎之前,先到scripting.dev.java.net project 这里看看是不是有人已经帮你做了工作,这样你就可以直接拿来用就行。
Scripting API
Scripting API是用于在Java里面编写脚本语言程序的API, 在Javax.script中可以找到Scripting API,我们就是用这个API来编写JavaScript程序,这个包里面有一个ScriptEngineManager类,它是使用Scriptng API 的入口,ScriptEngineManager可以通过Jar服务发现(service discovery)机制寻找合适的脚本引擎类(ScriptEngine),使用Scripting API的最简单方式只需下面三步
1、创建一个ScriptEngineManager对象
2、通过ScriptEngineManager获得ScriptEngine对象
3、用ScriptEngine的eval方法执行脚本
public static void main(String[] args) { ScriptEngineManager factory = new ScriptEngineManager(); ScriptEngine engine = factory.getEngineByName("JavaScript"); String script; try { script = "print('Hello')"; engine.eval(script);// 执行脚本 script = "1-23*9/3+77"; System.out.println(engine.eval(script).toString());// 不用对字符串做解析便可得到算式结果 engine.put("a", "一个字符串"); script = "print(a)"; engine.eval(script);// 脚本调用java对象 script = "function hello(name) { return 'Hello,' + name;}"; engine.eval(script); Invocable inv = (Invocable) engine; System.out.println(inv.invokeFunction("hello", "Scripting"));//java调用脚本方法 } catch (Exception e) { e.printStackTrace(); } }
Annotation | Retention | Target | Description |
Generated | Source |
ANNOTATION_TYPE, CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE |
用于标注生成的源代码 |
Resource | Runtime | TYPE, METHOD, FIELD | 用于标注所依赖的资源,容器据此注入外部资源依赖,有基于字段的注入和基于setter方法的注入两种方式 |
Resources | Runtime | TYPE | 同时标注多个外部依赖,容器会把所有这些外部依赖注入 |
PostConstruct | Runtime | METHOD | 标注当容器注入所有依赖之后运行的方法,用来进行依赖注入后的初始化工作,只有一个方法可以标注为PostConstruct |
PreDestroy | Runtime | METHOD | 当对象实例将要被从容器当中删掉之前,要执行的回调方法要标注为PreDestroy |
RunAs | Runtime | TYPE | 用于标注用什么安全角色来执行被标注类的方法,这个安全角色必须和Container 的Security角色一致的 |
RolesAllowed | Runtime | TYPE, METHOD | 用于标注允许执行被标注类或方法的安全角色,这个安全角色必须和Container 的Security角色一致的 |
PermitAll | Runtime | TYPE, METHOD | 允许所有角色执行被标注的类或方法 |
DenyAll | Runtime | TYPE, METHOD | 不允许任何角色执行被标注的类或方法,表明该类或方法不能在Java EE容器里面运行 |
DeclareRoles | Runtime | TYPE | 用来定义可以被应用程序检验的安全角色,通常用isUserInRole来检验安全角色 |