[轉(zhuǎn)]Java-JDK各個(gè)版本的新特性

JDK doc -https://docs.oracle.com/javase/8/docs/technotes/tools/unix/toc.html

1.5

1.自動(dòng)裝箱與拆箱:

2.枚舉(常用來設(shè)計(jì)單例模式)

3.靜態(tài)導(dǎo)入

4.可變參數(shù)

5.內(nèi)省

1.6

1.Web服務(wù)元數(shù)據(jù)

2.腳本語(yǔ)言支持

3.JTable的排序和過濾

4.更簡(jiǎn)單,更強(qiáng)大的JAX-WS

5.輕量級(jí)Http Server

6.嵌入式數(shù)據(jù)庫(kù)Derby

1.7

1缠捌,switch中可以使用字串了

2.運(yùn)用List tempList = new ArrayList<>(); 即泛型實(shí)例化類型自動(dòng)推斷

3.語(yǔ)法上支持集合,而不一定是數(shù)組

4.新增一些取環(huán)境信息的工具方法

5.Boolean類型反轉(zhuǎn),空指針安全,參與位運(yùn)算

6.兩個(gè)char間的equals

7.安全的加減乘除

8.map集合支持并發(fā)請(qǐng)求茵汰,且可以寫成 Map map = {name:"xxx",age:18};

1.8

1. 允許在接口中有默認(rèn)方法實(shí)現(xiàn)

2. Lambda表達(dá)式

3. 函數(shù)式接口

4. 方法和構(gòu)造函數(shù)引用

5. Lambda的范圍

6. 內(nèi)置函數(shù)式接口

7. Streams

8. Parallel Streams

9. Map

10. 時(shí)間日期API

11. Annotations

1.9

1. Jigsaw 項(xiàng)目;模塊化源碼

2. 簡(jiǎn)化進(jìn)程API

3. 輕量級(jí) JSON API

4. 錢和貨幣的API

5. 改善鎖爭(zhēng)用機(jī)制

6. 代碼分段緩存

7.智能Java編譯, 第二階段

8. HTTP 2.0客戶端

9. Kulla計(jì)劃: Java的REPL實(shí)現(xiàn)

Java9的14個(gè)新特性總結(jié)- http://geek.csdn.NET/news/detail/196632

---------------------------------------------------------------------------

JDK1.5新特性:

1.自動(dòng)裝箱與拆箱:

Integer?iObj?=?3;

System.out.println(iObj?+?12);

Integer?i1?=?137(-128--127范圍時(shí)氯夷,為true);

Integer?i2?=?137(-128--127范圍時(shí)缕减,為true);

System.out.println(i1?==?i2);?//false厨内,但是括號(hào)中時(shí)卻返回ture位迂,原因是Integer采用的是享元模式

Integer?i3?=?Integer.valueOf(213);

Integer?i4?=?Integer.valueOf(213);

System.out.println(i3==i4);//同上,另一種包裝形式

2.枚舉(常用來設(shè)計(jì)單例模式)

public?class?EnumTest?{

public?static?void?main(String[]?args)?{

WeekDay1?weekDay?=?WeekDay1.MON;

System.out.println(weekDay.nextDay());

WeekDay?weekDay2?=?WeekDay.FRI;

System.out.println(weekDay2);

System.out.println(weekDay2.name());

System.out.println(weekDay2.ordinal());

System.out.println(WeekDay.valueOf("SUN").toString());

System.out.println(WeekDay.values().length);

new?Date(300){};

}

public?enum?WeekDay{

SUN(1),MON(),TUE,WED,THI,FRI,SAT;

private?WeekDay(){System.out.println("first");}

private?WeekDay(int?day){System.out.println("second");}

}

public?enum?TrafficLamp{

RED(30){

public?TrafficLamp?nextLamp(){

return?GREEN;

}

},

GREEN(45){

public?TrafficLamp?nextLamp(){

return?YELLOW;

}

},

YELLOW(5){

public?TrafficLamp?nextLamp(){

return?RED;

}

};

public?abstract?TrafficLamp?nextLamp();

private?int?time;

private?TrafficLamp(int?time){this.time?=?time;}

}

}

3.靜態(tài)導(dǎo)入

import?static?java.lang.Math.*;

public?class?StaticImport?{

public?static?void?main(String[]?args){

int?x?=?1;

try?{

x++;

}?finally?{

System.out.println("template");

}

System.out.println(x);

System.out.println(max(3,?6));

System.out.println(abs(3?-?6));

}

}

4.可變參數(shù)

public?class?VarableParameter?{

public?static?void?main(String[]?args)?{

System.out.println(add(2,3));

System.out.println(add(2,3,5));

}

public?static?int?add(int?x,int...?args){

int?sum?=?x;

for(int?arg?:?args){

sum?+=?arg;

}

return?sum;

}

}

5.內(nèi)省

ReflectPoint?pt1?=?new?ReflectPoint(3,5);

BeanInfo?beanInfo?=?Introspector.getBeanInfo(pt1.getClass());

PropertyDescriptor[]?pds?=?beanInfo.getPropertyDescriptors();

Object?retVal?=?null;

for(PropertyDescriptor?pd?:?pds){

Method?methodGetX?=?pd.getReadMethod();

retVal?=?methodGetX.invoke(pt1);

}

jdk1.6新特性:

1.Web服務(wù)元數(shù)據(jù)

Java?里的Web服務(wù)元數(shù)據(jù)跟微軟的方案基本沒有語(yǔ)義上的區(qū)別,自從JDK5添加了元數(shù)據(jù)功能(Annotation)之后,SUN幾乎重構(gòu)了整個(gè)J2EE體?系,?由于變化很大,干脆將名字也重構(gòu)為Java?EE,?Java?EE(當(dāng)前版本為5.0)將元數(shù)據(jù)納入很多規(guī)范當(dāng)中,這其中就包括Web?Services的相關(guān)規(guī)范,?加入元數(shù)據(jù)之后的Web?Services服務(wù)器端編程模型就跟上面看到的C#片斷差不多了,?這顯然比以前的JAX-RPC編程模型簡(jiǎn)單(當(dāng)然,?Axis的編程模型也很簡(jiǎn)單).這里要談的Web服務(wù)元數(shù)據(jù)(JSR?181)只是Java?Web?服務(wù)規(guī)范中的一個(gè),它跟Common?Annotations,?JAXB2,?StAX,?SAAJ和JAX-WS等共同構(gòu)成Java?EE?5的Web?Services技術(shù)堆棧.

package?WebServices;

import?java.io.File;

import?java.io.IOException;

import?javax.jws.Oneway;

import?javax.jws.WebMethod;

import?javax.jws.WebParam;

import?javax.jws.WebResult;

import?javax.jws.WebService;

import?javax.xml.ws.Endpoint;

@WebService(targetNamespace="http://blog.csdn.net/chinajash",serviceName="HelloService")

public?class?WSProvider?{

@WebResult(name="Greetings")//自定義該方法返回值在WSDL中相關(guān)的描述

@WebMethod

public?String?sayHi(@WebParam(name="MyName")?String?name){

return?"Hi,"+name;?//@WebParam是自定義參數(shù)name在WSDL中相關(guān)的描述

}

@Oneway?//表明該服務(wù)方法是單向的,既沒有返回值,也不應(yīng)該聲明檢查異常

@WebMethod(action="printSystemTime",operationName="printSystemTime")//自定義該方法在WSDL中相關(guān)的描述

public?void?printTime(){

System.out.println(System.currentTimeMillis());

}

public?static?void?main(String[]?args)?{

Thread?wsPublisher?=?new?Thread(new?WSPublisher());

wsPublisher.start();

}

private?static?class?WSPublisher?implements?Runnable{

public?void?run()?{

//發(fā)布WSProvider到http://localhost:8888/chinajash/WSProvider這個(gè)地址,之前必須調(diào)用wsgen命令

//生成服務(wù)類WSProvider的支持類,命令如下:

//wsgen?-cp?.?WebServices.WSProvider

Endpoint.publish("http://localhost:8888/chinajash/WSProvider",new?WSProvider());

}

}

}

如果想看到Web?Services?Engine生成的WSDL文件是否遵守上面的元數(shù)據(jù),?我們沒有必要將上面的WSProvider部署到支持JSR-181的應(yīng)用服務(wù)器或Servlet形式的Web?Services?Engine,現(xiàn)在JDK6已經(jīng)提供了一個(gè)很簡(jiǎn)單的機(jī)制可以用來測(cè)試和發(fā)布Web?Services,下面講講如何在JDK6環(huán)境下發(fā)布Web?Services和查看生成的WSDL

1.將/bin加入path環(huán)境變量

2.在命令行下切換當(dāng)前目錄到WSProvider的class文件所在的目錄,運(yùn)行下面命令

wsgen?-cp?.?WebServices.WSProvider

在這個(gè)例子中會(huì)生成以下3個(gè)類的源代碼文件及class文件

SayHi

SayHiResponse

PrintTime

3.執(zhí)行如下代碼發(fā)布WSProvider到http://localhost:8888/chinajash/WSProvider,在這里可以執(zhí)行WSProvider類的main方法就可以

Endpoint.publish("http://localhost:8888/chinajash/WSProvider",new?WSProvider());

4.在瀏覽器輸入http://localhost:8888/chinajash/WSProvider?wsdl就可以看到生成的WSDL文件九秀,為了節(jié)省篇幅,這里就不把生成的WSDL文件貼上了遗嗽,大家可以自己動(dòng)手試試.

2.腳本語(yǔ)言支持

JDK6增加了對(duì)腳本語(yǔ)言的支持(JSR?223), 原理上是將腳本語(yǔ)言編譯成bytecode鼓蜒,這樣腳本語(yǔ)言也能享用Java平臺(tái)的諸多優(yōu)勢(shì)痹换,包括可移植性征字,安全等,另外娇豫,由于現(xiàn)在是編譯成 bytecode后再執(zhí)行匙姜,所以比原來邊解釋邊執(zhí)行效率要高很多。加入對(duì)腳本語(yǔ)言的支持后冯痢,對(duì)Java語(yǔ)言也提供了以下好處氮昧。

1、許多腳本語(yǔ)言都有動(dòng)態(tài)特性系羞,比如郭计,你不需要用一個(gè)變量之前先聲明它,你可以用一個(gè)變量存放完全不同類型的對(duì)象椒振,你不需要做強(qiáng)制類型轉(zhuǎn)換昭伸,因?yàn)檗D(zhuǎn)換都是自動(dòng)的。現(xiàn)在Java語(yǔ)言也可以通過對(duì)腳本語(yǔ)言的支持間接獲得這種靈活性澎迎。

2庐杨、?可以用腳本語(yǔ)言快速開發(fā)產(chǎn)品原型,因?yàn)楝F(xiàn)在可以Edit-Run夹供,而無(wú)需Edit-Compile-Run灵份,當(dāng)然,因?yàn)镴ava有非常好的IDE支持哮洽,我?們完全可以在IDE里面編輯源文件填渠,然后點(diǎn)擊運(yùn)行(隱含編譯),以此達(dá)到快速開發(fā)原型的目的鸟辅,所以這點(diǎn)好處基本上可以忽略氛什。

3、通過引入腳本語(yǔ)言可以輕松實(shí)現(xiàn)Java應(yīng)用程序的擴(kuò)展和自定義匪凉,我們可以把原來分布在在Java應(yīng)用程序中的配置邏輯枪眉,數(shù)學(xué)表達(dá)式和業(yè)務(wù)規(guī)則提取出來,轉(zhuǎn)用JavaScript來處理再层。

Sun的JDK6實(shí)現(xiàn)包含了一個(gè)基于Mozilla?Rhino的?腳本語(yǔ)言引擎贸铜,支持javascript,這并不是說明JDK6只支持JavaScript聂受,任何第三方都可以自己實(shí)現(xiàn)一個(gè)JSR-223兼容的腳本引擎?使得JDK6支持別的腳本語(yǔ)言蒿秦,比如,你想讓JDK6支持Ruby蛋济,那你可以自己按照J(rèn)SR?223 的規(guī)范實(shí)現(xiàn)一個(gè)Ruby的腳本引擎類渤早,具體一點(diǎn),你需要實(shí)現(xiàn)javax.script.ScriptEngine(簡(jiǎn)單起見瘫俊,可以繼承 javax.script.AbstractScriptEngine)和javax.script.ScriptEngineFactory兩個(gè)接口鹊杖。 當(dāng)然,在你實(shí)現(xiàn)自己的腳本語(yǔ)言引擎之前扛芽,先到scripting.dev.java.Netproject?這里看看是不是有人已經(jīng)幫你做了工作骂蓖,這樣你就可以直接拿來用就行。

Scripting?API

--------------------------------------------------------------------------------

Scripting?API是用于在Java里面編寫腳本語(yǔ)言程序的API川尖,?在Javax.script中可以找到Scripting?API登下,我們就是用這個(gè)API來編寫JavaScript程序,這個(gè)包里面有一個(gè)ScriptEngineManager類叮喳,它是使用Scripting?API的入口被芳,ScriptEngineManager可以通過jar服務(wù)發(fā)現(xiàn)(service?discovery)機(jī)制尋找合適的腳本引擎類(ScriptEngine),使用Scripting?API的最簡(jiǎn)單方式只需下面三步

1馍悟、創(chuàng)建一個(gè)ScriptEngineManager對(duì)象

2畔濒、通過ScriptEngineManager獲得ScriptEngine對(duì)象

3、用ScriptEngine的eval方法執(zhí)行腳本

下面是一個(gè)Hello?World程序

public?class?HelloScript?{public?static?void?main(String[]?args)?throws?Exception?{?????????ScriptEngineManager?factory?=?new?ScriptEngineManager();//step?1?????????ScriptEngine?engine?=?factory.getEngineByName("JavaScript");//Step?2?????????????engine.eval_r("print('Hello,?Scripting')");//Step?3?????}?????}運(yùn)行上面程序锣咒,控制臺(tái)會(huì)輸出Hello,?Scripting上面這個(gè)簡(jiǎn)單的Scripting程序演示了如何在Java里面運(yùn)行腳本語(yǔ)言侵状,除此之外,我們還可以利用Scripting?API實(shí)現(xiàn)以下功能1毅整、暴露Java對(duì)象為腳本語(yǔ)言的全局變量2趣兄、在Java中調(diào)用腳本語(yǔ)言的方法3、腳本語(yǔ)言可以實(shí)現(xiàn)Java的接口4悼嫉、腳本語(yǔ)言可以像Java一樣使用JDK平臺(tái)下的類下面的類演示了以上4種功能package?Scripting;import?java.io.File;import?javax.script.Invocable;import?javax.script.ScriptEngine;import?javax.script.ScriptEngineManager;import?javax.script.ScriptException;public?class?ScriptingAPITester?{?????public?static?void?main(String[]?args)?throws?Exception?{?????????ScriptEngineManager?manager?=?new?ScriptEngineManager();?????????ScriptEngine?engine?=?manager.getEngineByName("JavaScript");?????????testScriptVariables(engine);//演示如何暴露Java對(duì)象為腳本語(yǔ)言的全局變量??????????testInvokeScriptMethod(engine);//演示如何在Java中調(diào)用腳本語(yǔ)言的方法??????????testScriptInterface(engine);//演示腳本語(yǔ)言如何實(shí)現(xiàn)Java的接口??????????testUsingJDKClasses(engine);//演示腳本語(yǔ)言如何使用JDK平臺(tái)下的類?????}?????????public?static?void?testScriptVariables(ScriptEngine?engine)?throws?ScriptException{?????????File?file?=?new?File("test.txt");?????????engine.put("f",?file);?????????engine.eval_r("println('Total?Space:'+f.getTotalSpace())");?????????????}?????????public?static?void?testInvokeScriptMethod(ScriptEngine?engine)?throws?Exception{?????????String?script?=?"function?hello(name)?{?return?'Hello,'?+?name;}";?????????engine.eval_r(script);?????????Invocable?inv?=?(Invocable)?engine;?????????String?res?=?(String)inv.invokeFunction("hello",?"Scripting"?);?????????System.out.println("res:"+res);?????}?????????public?static?void?testScriptInterface(ScriptEngine?engine)?throws?ScriptException{?????????String?script?=?"var?obj?=?new?Object();?obj.run?=?function()?{?println('run?method?called');?}";?????????engine.eval_r(script);?????????Object?obj?=?engine.get("obj");?????????Invocable?inv?=?(Invocable)?engine;?????????Runnable?r?=?inv.getInterface(obj,Runnable.class);?????????Thread?th?=?new?Thread(r);?????????th.start();?????}?????????public?static?void?testUsingJDKClasses(ScriptEngine?engine)?throws?Exception{?????????//Packages是腳本語(yǔ)言里的一個(gè)全局變量,專用于訪問JDK的package?????????Stringjs=?"function?doSwing(t){var?f=new?Packages.javax.swing.JFrame(t);f.setSize(400,300);f.setVisible(true);}";?????????engine.eval_r(js);?????????Invocable?inv?=?(Invocable)?engine;?????????inv.invokeFunction("doSwing",?"Scripting?Swing"?);?????}}Scripting?Tool

--------------------------------------------------------------------------------

SUN 提供的JDK6中有一個(gè)命令行工具??jrunscript艇潭,你可以在/bin下面找到這個(gè)工 具,jrunscript是一個(gè)腳本語(yǔ)言的解釋程序戏蔑,它獨(dú)立于腳本語(yǔ)言蹋凝,但默認(rèn)是用JavaScript,我們可以用jrunscript來測(cè)試自己寫的 腳本語(yǔ)言是否正確辛臊,下面是一個(gè)在命令行運(yùn)行jrunscript的簡(jiǎn)單例子

jrunscript

js>println("Hello,JrunScript");

Hello,JrunScript

js>9*8

72.0

js>

3.JTable的排序和過濾

原來的JTable基本上是只能顯示數(shù)據(jù)仙粱,在JDK6新增了對(duì)JTable的排序和過濾功能,下面代碼演示了這兩個(gè)功能

public?class?JTableTester?{

static?String?data[][]?=?{

{"China","Beijing","Chinese"},

{"America","Washington","English"},

{"Korea","Seoul","Korean"},

{"Japan","Tokyo","Japanese"},

{"France","Paris","French"},

{"England","London","English"},

{"Germany","Berlin","German"},

};

static?String?titles[]?=?{"Country","Capital","Language"};

public?static?void?main(String[]?args)?{

DefaultTableModel?m?=?new?DefaultTableModel(data,titles);

JTable?t?=?new?JTable(m);

final?TableRowSorter?sorter?=?new?TableRowSorter(m);

t.setRowSorter(sorter);?//為JTable設(shè)置排序器

JScrollPane?sPane?=?new?JScrollPane();

sPane.setViewportView(t);

JPanel?p?=?new?JPanel();

p.setLayout(new?BoxLayout(p,BoxLayout.X_AXIS));

JLabel?l?=?new?JLabel("Criteria:");

final?JTextField?tf?=?new?JTextField();

JButton?b?=?new?JButton("Do?Filter");

p.add(l);

p.add(tf);

p.add(b);

b.addActionListener(new?ActionListener()?{

public?void?actionPerformed(ActionEvent?e)?{

if(tf.getText().length()==0){

sorter.setRowFilter(null);

}else{

sorter.setRowFilter(RowFilter.regexFilter(tf.getText()));//為JTable設(shè)置基于正則表達(dá)式的過濾條件

}

}

});

JFrame?f?=?new?JFrame("JTable?Sorting?and?Filtering");

f.getContentPane().add(sPane,BorderLayout.CENTER);

f.getContentPane().add(p,BorderLayout.SOUTH);

f.setSize(400,300);

f.setVisible(true);

}

}

運(yùn)行上面程序彻舰,單擊JTable的某一個(gè)title伐割,這個(gè)title對(duì)應(yīng)的列就會(huì)按照升序/降序重新排列;在下面的Criteria文本框中輸入"ese"刃唤,點(diǎn)擊"Do?Filter"按鈕隔心,JTable將只顯示帶有"ese"字符串的行,也就是China和Japan兩行尚胞,如果文本框里面什么都沒有硬霍,點(diǎn)擊"Do?Filter"按鈕,這時(shí)JTable會(huì)顯示所有的行笼裳。

4.更簡(jiǎn)單,更強(qiáng)大的JAX-WS

JAX-WS2.0的來歷

--------------------------------------------------------------------------------

JAX-WS(JSR-224)?是Java?Architecture?for?XML?Web?Services的縮寫,簡(jiǎn)單說就是一種用Java和XML開發(fā)Web?Services應(yīng)用程序的框架,?目前版本是2.0,?它是JAX-RPC?1.1的后續(xù)版本,?J2EE?1.4帶的就是JAX-RPC1.1,?而Java?EE?5里面包括了JAX-WS?2.0,但為了向后兼容,仍然支持JAX-RPC.?現(xiàn)在,SUN又把JAX-WS直接放到了Java?SE?6里面,由于JAX-WS會(huì)用到Common?Annotation(JSR?250),Java?Web?Services?Metadata(JSR?181),?JAXB2(JSR?222),?StAX(JSR?173),?所以SUN也必須把后幾個(gè)原屬于Java?EE范疇的Components下放到Java?SE,?現(xiàn)在我們可以清楚地理解了為什么Sun要把這些看似跟Java?SE沒有關(guān)系的Components放進(jìn)來,終極目的就是要在Java?SE里面支持Web?Services.

JAX-WS2.0的架構(gòu)

--------------------------------------------------------------------------------

JAX-WS不是一個(gè)孤立的框架,它依賴于眾多其他的規(guī)范,本質(zhì)上它由以下幾部分組成

1.用來開發(fā)Web?Services的Java?API

2.用來處理Marshal/Unmarshal的XML?Binding機(jī)制,JAX-WS2.0用JAXB2來處理Java?Object與XML之間的映射,Marshalling就是把Java?Object映射到XML,Unmarshalling則是把XML映射到Java?Object.之所以要做Java?Object與XML的映射,是因?yàn)樽罱K作為方法參數(shù)和返回值的Java?Object要通過網(wǎng)絡(luò)傳輸協(xié)議(一般是SOAP)傳送,這就要求必須對(duì)Java?Object做類似序列化和反序列化的工作,在SOAP中就是要用XML來表示Java?object的內(nèi)部狀態(tài)

3.眾多元數(shù)據(jù)(Annotations)會(huì)被JAX-WS用來描述Web?Services的相關(guān)類,包括Common?Annotations,?Web?Services?Metadata,?JAXB2的元數(shù)據(jù)和JAX-WS2.0規(guī)范自己的元數(shù)據(jù).

4.Annotation?Processing?Tool(APT) 是JAX-WS重要的組成部分,由于JAX-WS2.0規(guī)范用到很多元數(shù)據(jù),所以需要APT來處理眾多的Annotations. 在/bin下有兩個(gè)命令wsgen和wsimport,就是用到APT和Compiler?API來處理碰到的Annotations,wsgen可以為Web?Services?Provider產(chǎn)生并編譯必要的幫助類和相關(guān)支持文件,wsimport以WSDL作為輸入為Web?Service?Consumer產(chǎn)生并編譯必要的幫助類和相關(guān)支持文件.

5.JAX-WS還包括JAX-WS?Runtime與應(yīng)用服務(wù)器和工具之間的契約關(guān)系

JAX-WS2.0的編程模型

--------------------------------------------------------------------------------

現(xiàn)在用JAX-WS2.0來編寫Web?Services非常簡(jiǎn)單,不像JAX-RPC,JAX-WS可以把任意POJO暴露為Web?Services,服務(wù)類不需要實(shí)現(xiàn)接口,服務(wù)方法也沒有必要拋出RMI異常.下面介紹在JDK6環(huán)境下用JAX-WS2.0開發(fā)和測(cè)試Web?Services的步驟

1.編寫服務(wù)類,并用Web?Services?Metadata(JSR-181)標(biāo)注這個(gè)服務(wù)類,我用我的另一篇BlogJDK6的新特性之十:Web服務(wù)元數(shù)據(jù)中的WSProvider類作為服務(wù)類的例子,在此我重復(fù)貼一下WSProvider類的源代碼:

@WebService(targetNamespace="http://blog.csdn.net/chinajash",serviceName="HelloService")

public?class?WSProvider?{

@WebResult(name="Greetings")//自定義該方法返回值在WSDL中相關(guān)的描述

@WebMethod

public?String?sayHi(@WebParam(name="MyName")?String?name){

return?"Hi,"+name;?//@WebParam是自定義參數(shù)name在WSDL中相關(guān)的描述

}

@Oneway?//表明該服務(wù)方法是單向的,既沒有返回值,也不應(yīng)該聲明檢查異常

@WebMethod(action="printSystemTime",operationName="printSystemTime")//自定義該方法在WSDL中相關(guān)的描述

public?void?printTime(){

System.out.println(System.currentTimeMillis());

}

public?static?void?main(String[]?args)?{

Thread?wsPublisher?=?new?Thread(new?WSPublisher());

wsPublisher.start();

}

private?static?class?WSPublisher?implements?Runnable{

public?void?run()?{

//發(fā)布WSProvider到http://localhost:8888/chinajash/WSProvider這個(gè)地址,之前必須調(diào)用wsgen命令

//生成服務(wù)類WSProvider的支持類,命令如下:

//wsgen?-cp?.?WebServices.WSProvider

Endpoint.publish("http://localhost:8888/chinajash/WSProvider",new?WSProvider());

}

}

}

2.用wsgen生成上面服務(wù)類的必要的幫助類,然后調(diào)用用EndPoint類的靜態(tài)方法publish發(fā)布服務(wù)類(步驟請(qǐng)參考我的另一篇Blog?JDK6的新特性之十:Web服務(wù)元數(shù)據(jù)),我在這里是將服務(wù)類發(fā)布到http://localhost:8888/chinajash/WSProvider

3.用wsimport為服務(wù)消費(fèi)者(也就是服務(wù)的客戶端)生成必要的幫助類,命令如下:

wsimport?http://localhost:8888/chinajash/WSProvider?wsdl

這會(huì)在<當(dāng)前目錄>\net\csdn\blog\chinajash下生成客戶端的幫助類,在這個(gè)例子中會(huì)生成7個(gè)類

HelloService.class

ObjectFactory.class

package-info.class

PrintSystemTime.class

SayHi.class

SayHiResponse.class

WSProvider.class

4.在客戶端用下面代碼即可調(diào)用步驟1定義的Web?Service

HelloService?hs?=?new?HelloService();

WSProvider?ws?=?hs.getWSProviderPort();

System.out.println(ws.sayHi("chinajash"));

ws.printSystemTime();

調(diào)用上述代碼后客戶端控制臺(tái)輸出

hi,chinajash

服務(wù)端控制臺(tái)輸出服務(wù)器當(dāng)前系統(tǒng)時(shí)間

5.輕量級(jí)Http?Server

JDK6的新特性之五:輕量級(jí)Http?Server

JDK6提供了一個(gè)簡(jiǎn)單的Http?Server?API,據(jù)此我們可以構(gòu)建自己的嵌入式Http?Server,它支持Http和Https協(xié)議,提供了HTTP1.1的部分實(shí)現(xiàn)唯卖,沒有被實(shí)現(xiàn)的那部分可以通過擴(kuò)展已有的Http?Server?API 來實(shí)現(xiàn),程序員必須自己實(shí)現(xiàn)HttpHandler接口,HttpServer會(huì)調(diào)用HttpHandler實(shí)現(xiàn)類的回調(diào)方法來處理客戶端請(qǐng)求,在這里, 我們把一個(gè)Http請(qǐng)求和它的響應(yīng)稱為一個(gè)交換,包裝成HttpExchange類,HttpServer負(fù)責(zé)將HttpExchange傳給 HttpHandler實(shí)現(xiàn)類的回調(diào)方法.下面代碼演示了怎樣創(chuàng)建自己的Http?Server

public?class?HTTPServerAPITester?{

public?static?void?main(String[]?args)?{

try?{

HttpServer?hs?=?HttpServer.create(new?InetSocketAddress(8888),0);//設(shè)置HttpServer的端口為8888

hs.createContext("/chinajash",?new?MyHandler());//用MyHandler類內(nèi)處理到/chinajash的請(qǐng)求

hs.setExecutor(null);?//?creates?a?default?executor

hs.start();

}?catch?(IOException?e)?{

e.printStackTrace();

}

}

}

class?MyHandler?implements?HttpHandler?{

public?void?handle(HttpExchange?t)?throws?IOException?{

InputStream?is?=?t.getRequestBody();

String?response?=?"

Happy?New?Year?2007!--Chinajash

";

t.sendResponseHeaders(200,?response.length());

OutputStream?os?=?t.getResponseBody();

os.write(response.getBytes());

os.close();

}

}

運(yùn)行程序后,在瀏覽器內(nèi)輸入http://localhost:8888/xx,瀏覽器輸出

6.嵌入式數(shù)據(jù)庫(kù)Derby

Derby是IBM送給開源社區(qū)的又一個(gè)禮物粱玲,是一個(gè)pure?java的數(shù)據(jù)庫(kù),現(xiàn)在已經(jīng)被列入到j(luò)ava1.6中拜轨。

不知道對(duì)于大數(shù)據(jù)量的性能如何抽减,但傳說中啟動(dòng)derby只會(huì)給JVM添加2M的內(nèi)存,對(duì)那些小數(shù)據(jù)庫(kù)應(yīng)用橄碾,比如像用access那種應(yīng)該是挺有誘惑力的卵沉。

另外,麻雀雖小法牲,五臟俱全史汗,功能要比access多得多咯,包括事務(wù)處理拒垃,并發(fā)停撞,觸發(fā)器都有,管理又簡(jiǎn)單恶复,因此自己用來做點(diǎn)工具正好合適怜森。

廢話少說,介紹一下我折騰了半天的經(jīng)驗(yàn)吧谤牡。

我的Derby配置過程:

1副硅,下載db-derby-10.1.3.1-bin.tar.gz,derby_core_plugin_10.1.3.zip和derby_ui_plugin_1.1.0.zip,把兩個(gè)插件安裝到eclipse上

2翅萤,打開ecllipse,新建一個(gè)project

3恐疲,右鍵這個(gè)project,選擇Apache?Derby套么,再選擇add?apache?derby?native培己,發(fā)現(xiàn)只是給我的project添加了幾個(gè)derby的jar,還不是在我看著順眼的lib目錄里胚泌,索性干掉省咨,換上db-derby-?10.1.3.1-bin.tar.gz解壓出來以后lib目錄下的jar文件,在Build?Path里設(shè)置一下玷室;

4零蓉,右鍵Project,在apache?derby里選擇start?apache?derby?network?server穷缤,控制臺(tái)可以看到derby啟動(dòng)后打出的“服務(wù)器準(zhǔn)備在端口?1527?上接受連接敌蜂。”

5津肛,右鍵Project章喉,在apache?derby里選擇ij(Interactive?SQL),啟動(dòng)SQL控制臺(tái);

6秸脱,輸入connect?jdbc:derby:testdb;create=true;?注意要有單引號(hào)落包,可以在工程跟目錄下創(chuàng)建testdb數(shù)據(jù)庫(kù),可以看到一個(gè)新建的目錄testdb撞反,那里的文件就是數(shù)據(jù)庫(kù)咯妥色;

7,用標(biāo)準(zhǔn)的SQL語(yǔ)句來建一個(gè)數(shù)據(jù)庫(kù)試試:

create?table?test?(a?varchar(4)?not?null,?b?char(2)?primary?key);

居然可以用遏片,太神奇了,呵呵

8撮竿,再插入一條語(yǔ)句試試呢吮便,insert?into?test(a,b)?values(a,11);,嗯幢踏,不錯(cuò)髓需,可以用select?查出來的哦。

9房蝉,再插一下:insert?into?test(a,b)?values(a,11);僚匆,哦哦,報(bào)錯(cuò)了搭幻,“錯(cuò)誤?23505:語(yǔ)句異常終止咧擂,因?yàn)樗鼘?dǎo)致“TEST”上所定義的“SQL060710092132480”標(biāo)識(shí)的唯一或主鍵約束或唯一索引中出現(xiàn)重復(fù)鍵值√刺#”?呵呵松申。

10,好了俯逾,現(xiàn)在可以像你控制的其他數(shù)據(jù)庫(kù)一樣來控制Derby了贸桶。

如果上述方法不行,或者你習(xí)慣了在eclipse之外使用和管理數(shù)據(jù)庫(kù)桌肴,那么可以很方便的把Derby“裝”在系統(tǒng)里皇筛。下面我說一下步驟:

1贮勃,把db-derby-10.1.3.1-bin.tar.gz解壓到c:\derby,使lib和framework兩個(gè)目錄在c:\derby下邊即可

2只嚣,設(shè)置環(huán)境變量

設(shè)置一個(gè)c:\derby\framework\embeded\bin或c:\derby\framework\NetworkServe\bin到Path中桩撮,這樣我們就可以直接執(zhí)行上邊介紹的connect這樣的命令而不用每次鉆到那個(gè)目錄下去執(zhí)行了

設(shè)置c:\derby\lib\derby.jar;c:\derby\lib\derbytoos.jar到CLASSPATH中沼沈,以便讓這些java編成的命令能夠正確執(zhí)行珍昨;

3挂洛,打開cmd

4佩谣,敲入startNetworkServer凡怎,可以看到像在eclisp中提示的那樣啟動(dòng)了server

5悉稠,再打開一個(gè)cmd,敲入sysinfo,可以看到derby的環(huán)境信息了宫蛆,注意在java?user?dir這一項(xiàng),也許是java用戶目錄上和上邊看到的會(huì)有所不同哦,這樣在connect?jdbc:derby:testdb;create=true;的建的數(shù)據(jù)庫(kù)目錄就不一樣咯耀盗。

6想虎,敲入ij,好了叛拷,進(jìn)入到上邊的交互界面舌厨,可以建一個(gè)數(shù)據(jù)庫(kù)看看了。

7忿薇,最后在另外一個(gè)cmd中敲入stopNetworkServer就可以關(guān)閉數(shù)據(jù)庫(kù)了裙椭。

如果你兩種方法都試過了,那么需要注意的署浩,還是上邊步驟5的問題揉燃,這個(gè)問題是你可能隨時(shí)會(huì)啟動(dòng)一個(gè)數(shù)據(jù)庫(kù)或新建一個(gè)數(shù)據(jù)庫(kù),但如果你剛剛使用derby筋栋,你可能還沒有察覺炊汤。

derby實(shí)際上有兩種啟動(dòng)方式,一種是嵌入式的弊攘,一種是網(wǎng)絡(luò)服務(wù)器的啟動(dòng)抢腐。

1,我們?cè)趀clipse中右鍵start?apache?derby?network?server那個(gè)襟交,就是網(wǎng)絡(luò)服務(wù)器的啟動(dòng)方式迈倍,在這種方式下可以用另外一臺(tái)計(jì)算機(jī)在ij中以:

connect?jdbc:derby://192.168.0.28:1527/testdb

的方式進(jìn)行鏈接。

2婿着,第二種啟動(dòng)方式是在ij里邊就直接

connect?jdbc:derby:testdb

這實(shí)際是在連當(dāng)前配置環(huán)境下java?user?dir下那個(gè)目錄的數(shù)據(jù)庫(kù)授瘦。

看到這里可能有點(diǎn)糊涂了,這么就會(huì)出問題了那竟宋?

實(shí)際上derby的訪問更像是一種使用derby?driver對(duì)本地文件系統(tǒng)的訪問提完,不管啟動(dòng)不啟動(dòng)網(wǎng)絡(luò)服務(wù)器,都可以用driver訪問本地的數(shù)據(jù)庫(kù)丘侠。這樣徒欣,在ij里邊像第二種方式那樣建立連接是完全可以的。啟動(dòng)了網(wǎng)絡(luò)服務(wù)器蜗字,只不過是能夠讓其他主機(jī)訪問罷了打肝。

另外一個(gè)問題是,在eclipse中和在系統(tǒng)中連接服務(wù)器挪捕,在connect的時(shí)候這個(gè)當(dāng)前配置環(huán)境是不一樣的粗梭,eclipse默認(rèn)工程所在路徑是數(shù)據(jù)庫(kù)的所在路徑,而在系統(tǒng)中“裝”derby則會(huì)認(rèn)為?c:\document?and?settings下邊那個(gè)用戶目錄是數(shù)據(jù)庫(kù)的所在路徑级零。

jdk1.7新特性:

1断医,switch中可以使用字串了

String?s?=?"test";

switch?(s)?{

case?"test"?:

System.out.println("test");

case?"test1"?:

System.out.println("test1");

break?;

default?:

System.out.println("break");

break?;

}

2.運(yùn)用List?tempList?=?new?ArrayList<>();?即泛型實(shí)例化類型自動(dòng)推斷

3.語(yǔ)法上支持集合,而不一定是數(shù)組

final?List?piDigits?=?[?1,2,3,4,5,8?];

4.新增一些取環(huán)境信息的工具方法

File?System.getJavaIoTempDir()?//?IO臨時(shí)文件夾

File?System.getJavaHomeDir()?//?JRE的安裝目錄

File?System.getUserHomeDir()?//?當(dāng)前用戶目錄

File?System.getUserDir()?//?啟動(dòng)java進(jìn)程時(shí)所在的目錄5

5.Boolean類型反轉(zhuǎn),空指針安全,參與位運(yùn)算

Boolean?Booleans.negate(Boolean?booleanObj)

True?=>?False?,?False?=>?True,?Null?=>?Null

boolean?Booleans.and(boolean[]?array)

boolean?Booleans.or(boolean[]?array)

boolean?Booleans.xor(boolean[]?array)

boolean?Booleans.and(Boolean[]?array)

boolean?Booleans.or(Boolean[]?array)

boolean?Booleans.xor(Boolean[]?array)

6.兩個(gè)char間的equals

boolean?Character.equalsIgnoreCase(char?ch1,?char?ch2)

7.安全的加減乘除

int?Math.safeToInt(long?value)

int?Math.safeNegate(int?value)

long?Math.safeSubtract(long?value1,?int?value2)

long?Math.safeSubtract(long?value1,?long?value2)

int?Math.safeMultiply(int?value1,?int?value2)

long?Math.safeMultiply(long?value1,?int?value2)

long?Math.safeMultiply(long?value1,?long?value2)

long?Math.safeNegate(long?value)

int?Math.safeAdd(int?value1,?int?value2)

long?Math.safeAdd(long?value1,?int?value2)

long?Math.safeAdd(long?value1,?long?value2)

int?Math.safeSubtract(int?value1,?int?value2)

8.map集合支持并發(fā)請(qǐng)求鉴嗤,且可以寫成Map?map?=?{name:"xxx",age:18};

--------------------------------------------------------------------------------------------------------------

歡迎閱讀我編寫的Java 8介紹斩启。本教程將帶領(lǐng)你一步一步地認(rèn)識(shí)這門語(yǔ)言的新特性。通過簡(jiǎn)單明了的代碼示例醉锅,你將會(huì)學(xué)習(xí)到如何使用默認(rèn)接口方法兔簇,Lambda表達(dá)式,方法引用和重復(fù)注解硬耍÷⑺觯看完這篇教程后,你還將對(duì)最新推出的API有一定的了解默垄,例如:流控制此虑,函數(shù)式接口,map擴(kuò)展和新的時(shí)間日期API等等口锭。

目 錄[ - ]

允許在接口中有默認(rèn)方法實(shí)現(xiàn)

Lambda表達(dá)式

函數(shù)式接口

方法和構(gòu)造函數(shù)引用

Lambda的范圍

內(nèi)置函數(shù)式接口

Streams

Parallel Streams

Map

時(shí)間日期API

Annotations

總結(jié)

允許在接口中有默認(rèn)方法實(shí)現(xiàn)

Java 8 允許我們使用default關(guān)鍵字,為接口聲明添加非抽象的方法實(shí)現(xiàn)介杆。這個(gè)特性又被稱為擴(kuò)展方法鹃操。下面是我們的第一個(gè)例子:

Java代碼

interfaceFormula?{

doublecalculate(inta);

defaultdoublesqrt(inta)?{

returnMath.sqrt(a);

}

}

在接口Formula中,除了抽象方法caculate以外春哨,還定義了一個(gè)默認(rèn)方法sqrt荆隘。Formula的實(shí)現(xiàn)類只需要實(shí)現(xiàn)抽象方法caculate就可以了。默認(rèn)方法sqrt可以直接使用赴背。

Java代碼

Formula?formula?=newFormula()?{

@Override

publicdoublecalculate(inta)?{

returnsqrt(a?*100);

}

};

formula.calculate(100);//?100.0

formula.sqrt(16);//?4.0

formula對(duì)象以匿名對(duì)象的形式實(shí)現(xiàn)了Formula接口椰拒。代碼很啰嗦:用了6行代碼才實(shí)現(xiàn)了一個(gè)簡(jiǎn)單的計(jì)算功能:a*100開平方根。我們?cè)谙乱还?jié)會(huì)看到凰荚,Java 8 還有一種更加優(yōu)美的方法燃观,能夠?qū)崿F(xiàn)包含單個(gè)函數(shù)的對(duì)象。

Lambda表達(dá)式

讓我們從最簡(jiǎn)單的例子開始便瑟,來學(xué)習(xí)如何對(duì)一個(gè)string列表進(jìn)行排序缆毁。我們首先使用Java 8之前的方法來實(shí)現(xiàn):

Java代碼

List?names?=?Arrays.asList("peter","anna","mike","xenia");

Collections.sort(names,newComparator()?{

@Override

publicintcompare(String?a,?String?b)?{

returnb.compareTo(a);

}

});

靜態(tài)工具方法Collections.sort接受一個(gè)list,和一個(gè)Comparator接口作為輸入?yún)?shù)到涂,Comparator的實(shí)現(xiàn)類可 以對(duì)輸入的list中的元素進(jìn)行比較脊框。通常情況下,你可以直接用創(chuàng)建匿名Comparator對(duì)象践啄,并把它作為參數(shù)傳遞給sort方法浇雹。

除了創(chuàng)建匿名對(duì)象以外,Java 8 還提供了一種更簡(jiǎn)潔的方式屿讽,Lambda表達(dá)式昭灵。

Java代碼

Collections.sort(names,?(String?a,?String?b)?->?{

returnb.compareTo(a);

});

你可以看到,這段代碼就比之前的更加簡(jiǎn)短和易讀。但是虎锚,它還可以更加簡(jiǎn)短:

Java代碼

Collections.sort(names,?(String?a,?String?b)?->?b.compareTo(a));

只要一行代碼硫痰,包含了方法體。你甚至可以連大括號(hào)對(duì){}和return關(guān)鍵字都省略不要窜护。不過這還不是最短的寫法:

Java代碼

Collections.sort(names,?(a,?b)?->?b.compareTo(a));

Java編譯器能夠自動(dòng)識(shí)別參數(shù)的類型效斑,所以你就可以省略掉類型不寫。讓我們?cè)偕钊氲匮芯恳幌耹ambda表達(dá)式的威力吧柱徙。

函數(shù)式接口

Lambda表達(dá)式如何匹配Java的類型系統(tǒng)缓屠?每一個(gè)lambda都能夠通過一個(gè)特定的接口,與一個(gè)給定的類型進(jìn)行匹配护侮。一個(gè)所謂的函數(shù)式接口必須要有 且僅有一個(gè)抽象方法聲明敌完。每個(gè)與之對(duì)應(yīng)的lambda表達(dá)式必須要與抽象方法的聲明相匹配。由于默認(rèn)方法不是抽象的羊初,因此你可以在你的函數(shù)式接口里任意添 加默認(rèn)方法滨溉。

任意只包含一個(gè)抽象方法的接口,我們都可以用來做成lambda表達(dá)式长赞。為了讓你定義的接口滿足要求晦攒,你應(yīng)當(dāng)在接口前加上@FunctionalInterface 標(biāo)注。編譯器會(huì)注意到這個(gè)標(biāo)注得哆,如果你的接口中定義了第二個(gè)抽象方法的話脯颜,編譯器會(huì)拋出異常。

舉例:

Java代碼

@FunctionalInterface

interfaceConverter?{

T?convert(F?from);

}

Converter?converter?=?(from)?->?Integer.valueOf(from);

Integer?converted?=?converter.convert("123");

System.out.println(converted);//?123

注意贩据,如果你不寫@FunctionalInterface 標(biāo)注栋操,程序也是正確的。

方法和構(gòu)造函數(shù)引用

上面的代碼實(shí)例可以通過靜態(tài)方法引用饱亮,使之更加簡(jiǎn)潔:

Java代碼

Converter?converter?=?Integer::valueOf;

Integer?converted?=?converter.convert("123");

System.out.println(converted);//?123

Java 8 允許你通過::關(guān)鍵字獲取方法或者構(gòu)造函數(shù)的的引用矾芙。上面的例子就演示了如何引用一個(gè)靜態(tài)方法。而且近尚,我們還可以對(duì)一個(gè)對(duì)象的方法進(jìn)行引用:

Java代碼

classSomething?{

String?startsWith(String?s)?{

returnString.valueOf(s.charAt(0));

}

}

Something?something?=newSomething();

Converter?converter?=?something::startsWith;

String?converted?=?converter.convert("Java");

System.out.println(converted);//?"J"

讓我們看看如何使用::關(guān)鍵字引用構(gòu)造函數(shù)蠕啄。首先我們定義一個(gè)示例bean,包含不同的構(gòu)造方法:

Java代碼

classPerson?{

String?firstName;

String?lastName;

Person()?{}

Person(String?firstName,?String?lastName)?{

this.firstName?=?firstName;

this.lastName?=?lastName;

}

}

接下來戈锻,我們定義一個(gè)person工廠接口歼跟,用來創(chuàng)建新的person對(duì)象:

Java代碼

interfacePersonFactory?{

P?create(String?firstName,?String?lastName);

}

然后我們通過構(gòu)造函數(shù)引用來把所有東西拼到一起,而不是像以前一樣格遭,通過手動(dòng)實(shí)現(xiàn)一個(gè)工廠來這么做哈街。

Java代碼

PersonFactory?personFactory?=?Person::new;

Person?person?=?personFactory.create("Peter","Parker");

我們通過Person::new來創(chuàng)建一個(gè)Person類構(gòu)造函數(shù)的引用。Java編譯器會(huì)自動(dòng)地選擇合適的構(gòu)造函數(shù)來匹配PersonFactory.create函數(shù)的簽名拒迅,并選擇正確的構(gòu)造函數(shù)形式骚秦。

Lambda的范圍

對(duì)于lambdab表達(dá)式外部的變量她倘,其訪問權(quán)限的粒度與匿名對(duì)象的方式非常類似。你能夠訪問局部對(duì)應(yīng)的外部區(qū)域的局部final變量作箍,以及成員變量和靜態(tài)變量硬梁。

訪問局部變量

我們可以訪問lambda表達(dá)式外部的final局部變量:

Java代碼

finalintnum?=1;

Converter?stringConverter?=

(from)?->?String.valueOf(from?+?num);

stringConverter.convert(2);//?3

但是與匿名對(duì)象不同的是,變量num并不需要一定是final胞得。下面的代碼依然是合法的:

Java代碼

intnum?=1;

Converter?stringConverter?=

(from)?->?String.valueOf(from?+?num);

stringConverter.convert(2);//?3

然而荧止,num在編譯的時(shí)候被隱式地當(dāng)做final變量來處理。下面的代碼就不合法:

Java代碼

intnum?=1;

Converter?stringConverter?=

(from)?->?String.valueOf(from?+?num);

num?=3;

在lambda表達(dá)式內(nèi)部企圖改變num的值也是不允許的阶剑。

訪問成員變量和靜態(tài)變量

與局部變量不同跃巡,我們?cè)趌ambda表達(dá)式的內(nèi)部能獲取到對(duì)成員變量或靜態(tài)變量的讀寫權(quán)。這種訪問行為在匿名對(duì)象里是非常典型的牧愁。

Java代碼

classLambda4?{

staticintouterStaticNum;

intouterNum;

voidtestScopes()?{

Converter?stringConverter1?=?(from)?->?{

outerNum?=23;

returnString.valueOf(from);

};

Converter?stringConverter2?=?(from)?->?{

outerStaticNum?=72;

returnString.valueOf(from);

};

}

}

訪問默認(rèn)接口方法

還記得第一節(jié)里面formula的那個(gè)例子么素邪? 接口Formula定義了一個(gè)默認(rèn)的方法sqrt,該方法能夠訪問formula所有的對(duì)象實(shí)例猪半,包括匿名對(duì)象兔朦。這個(gè)對(duì)lambda表達(dá)式來講則無(wú)效。

默認(rèn)方法無(wú)法在lambda表達(dá)式內(nèi)部被訪問磨确。因此下面的代碼是無(wú)法通過編譯的:

Java代碼

Formula?formula?=?(a)?->?sqrt(?a?*100);

內(nèi)置函數(shù)式接口

JDK 1.8 API中包含了很多內(nèi)置的函數(shù)式接口烘绽。有些是在以前版本的Java中大家耳熟能詳?shù)模鏑omparator接口俐填,或者Runnable接口。對(duì)這些現(xiàn) 成的接口進(jìn)行實(shí)現(xiàn)翔忽,可以通過@FunctionalInterface 標(biāo)注來啟用Lambda功能支持英融。

此外,Java 8 API 還提供了很多新的函數(shù)式接口歇式,來降低程序員的工作負(fù)擔(dān)驶悟。有些新的接口已經(jīng)在Google Guava庫(kù)中很有名了。如果你對(duì)這些庫(kù)很熟的話材失,你甚至閉上眼睛都能夠想到痕鳍,這些接口在類庫(kù)的實(shí)現(xiàn)過程中起了多么大的作用。

Predicates

Predicate是一個(gè)布爾類型的函數(shù)龙巨,該函數(shù)只有一個(gè)輸入?yún)?shù)笼呆。Predicate接口包含了多種默認(rèn)方法,用于處理復(fù)雜的邏輯動(dòng)詞(and, or旨别,negate):

Java代碼

Predicate?predicate?=?(s)?->?s.length()?>0;

predicate.test("foo");//?true

predicate.negate().test("foo");//?false

Predicate?nonNull?=?Objects::nonNull;

Predicate?isNull?=?Objects::isNull;

Predicate?isEmpty?=?String::isEmpty;

Predicate?isNotEmpty?=?isEmpty.negate();

Functions

Function接口接收一個(gè)參數(shù)诗赌,并返回單一的結(jié)果。默認(rèn)方法可以將多個(gè)函數(shù)串在一起(compse, andThen):

Java代碼

Function?toInteger?=?Integer::valueOf;

Function?backToString?=?toInteger.andThen(String::valueOf);

backToString.apply("123");//?"123"

Suppliers

Supplier接口產(chǎn)生一個(gè)給定類型的結(jié)果秸弛。與Function不同的是铭若,Supplier沒有輸入?yún)?shù)洪碳。

Java代碼

Supplier?personSupplier?=?Person::new;

personSupplier.get();//?new?Person

Consumers

Consumer代表了在一個(gè)輸入?yún)?shù)上需要進(jìn)行的操作。

Java代碼

Consumer?greeter?=?(p)?->?System.out.println("Hello,?"+?p.firstName);

greeter.accept(newPerson("Luke","Skywalker"));

Comparators

Comparator接口在早期的Java版本中非常著名叼屠。Java 8 為這個(gè)接口添加了不同的默認(rèn)方法瞳腌。

Java代碼

Comparator?comparator?=?(p1,?p2)?->?p1.firstName.compareTo(p2.firstName);

Person?p1?=newPerson("John","Doe");

Person?p2?=newPerson("Alice","Wonderland");

comparator.compare(p1,?p2);//?>?0

comparator.reversed().compare(p1,?p2);//?<?0

Optionals

Optional不是一個(gè)函數(shù)式接口,而是一個(gè)精巧的工具接口镜雨,用來防止NullPointerEception產(chǎn)生嫂侍。這個(gè)概念在下一節(jié)會(huì)顯得很重要,所以我們?cè)谶@里快速地瀏覽一下Optional的工作原理冷离。

Optional是一個(gè)簡(jiǎn)單的值容器吵冒,這個(gè)值可以是null,也可以是non-null西剥”云埽考慮到一個(gè)方法可能會(huì)返回一個(gè)non-null的值,也可能返回一個(gè)空值瞭空。為了不直接返回null揪阿,我們?cè)贘ava 8中就返回一個(gè)Optional。

Java代碼

Optional?optional?=?Optional.of("bam");

optional.isPresent();//?true

optional.get();//?"bam"

optional.orElse("fallback");//?"bam"

optional.ifPresent((s)?->?System.out.println(s.charAt(0)));//?"b"

Streams

java.util.Stream表示了某一種元素的序列咆畏,在這些元素上可以進(jìn)行各種操作南捂。Stream操作可以是中間操作,也可以是完結(jié)操作旧找。完結(jié)操作 會(huì)返回一個(gè)某種類型的值溺健,而中間操作會(huì)返回流對(duì)象本身,并且你可以通過多次調(diào)用同一個(gè)流操作方法來將操作結(jié)果串起來(就像StringBuffer的 append方法一樣————譯者注)钮蛛。Stream是在一個(gè)源的基礎(chǔ)上創(chuàng)建出來的鞭缭,例如java.util.Collection中的list或者 set(map不能作為Stream的源)。Stream操作往往可以通過順序或者并行兩種方式來執(zhí)行魏颓。

我們先了解一下序列流岭辣。首先,我們通過string類型的list的形式創(chuàng)建示例數(shù)據(jù):

Java代碼

List?stringCollection?=newArrayList<>();

stringCollection.add("ddd2");

stringCollection.add("aaa2");

stringCollection.add("bbb1");

stringCollection.add("aaa1");

stringCollection.add("bbb3");

stringCollection.add("ccc");

stringCollection.add("bbb2");

stringCollection.add("ddd1");

Java 8中的Collections類的功能已經(jīng)有所增強(qiáng)甸饱,你可以之直接通過調(diào)用Collections.stream()或者Collection.parallelStream()方法來創(chuàng)建一個(gè)流對(duì)象沦童。下面的章節(jié)會(huì)解釋這個(gè)最常用的操作。

Filter

Filter接受一個(gè)predicate接口類型的變量叹话,并將所有流對(duì)象中的元素進(jìn)行過濾偷遗。該操作是一個(gè)中間操作,因此它允許我們?cè)诜祷亟Y(jié)果的基 礎(chǔ)上再進(jìn)行其他的流操作(forEach)渣刷。ForEach接受一個(gè)function接口類型的變量鹦肿,用來執(zhí)行對(duì)每一個(gè)元素的操作。ForEach是一個(gè) 中止操作辅柴。它不返回流箩溃,所以我們不能再調(diào)用其他的流操作瞭吃。

Java代碼

stringCollection

.stream()

.filter((s)?->?s.startsWith("a"))

.forEach(System.out::println);

//?"aaa2",?"aaa1"

Sorted

Sorted是一個(gè)中間操作,能夠返回一個(gè)排過序的流對(duì)象的視圖涣旨。流對(duì)象中的元素會(huì)默認(rèn)按照自然順序進(jìn)行排序歪架,除非你自己指定一個(gè)Comparator接口來改變排序規(guī)則。

Java代碼

stringCollection

.stream()

.sorted()

.filter((s)?->?s.startsWith("a"))

.forEach(System.out::println);

//?"aaa1",?"aaa2"

一定要記住霹陡,sorted只是創(chuàng)建一個(gè)流對(duì)象排序的視圖和蚪,而不會(huì)改變?cè)瓉砑现性氐捻樞颉T瓉韘tring集合中的元素順序是沒有改變的烹棉。

Java代碼

System.out.println(stringCollection);

//?ddd2,?aaa2,?bbb1,?aaa1,?bbb3,?ccc,?bbb2,?ddd1

Map

map是一個(gè)對(duì)于流對(duì)象的中間操作攒霹,通過給定的方法,它能夠把流對(duì)象中的每一個(gè)元素對(duì)應(yīng)到另外一個(gè)對(duì)象上浆洗。下面的例子就演示了如何把每個(gè) string都轉(zhuǎn)換成大寫的string. 不但如此催束,你還可以把每一種對(duì)象映射成為其他類型。對(duì)于帶泛型結(jié)果的流對(duì)象伏社,具體的類型還要由傳遞給map的泛型方法來決定抠刺。

Java代碼

stringCollection

.stream()

.map(String::toUpperCase)

.sorted((a,?b)?->?b.compareTo(a))

.forEach(System.out::println);

//?"DDD2",?"DDD1",?"CCC",?"BBB3",?"BBB2",?"AAA2",?"AAA1"

Match

匹配操作有多種不同的類型,都是用來判斷某一種規(guī)則是否與流對(duì)象相互吻合的摘昌。所有的匹配操作都是終結(jié)操作速妖,只返回一個(gè)boolean類型的結(jié)果。

Java代碼

booleananyStartsWithA?=

stringCollection

.stream()

.anyMatch((s)?->?s.startsWith("a"));

System.out.println(anyStartsWithA);//?true

booleanallStartsWithA?=

stringCollection

.stream()

.allMatch((s)?->?s.startsWith("a"));

System.out.println(allStartsWithA);//?false

booleannoneStartsWithZ?=

stringCollection

.stream()

.noneMatch((s)?->?s.startsWith("z"));

System.out.println(noneStartsWithZ);//?true

Count

Count是一個(gè)終結(jié)操作聪黎,它的作用是返回一個(gè)數(shù)值罕容,用來標(biāo)識(shí)當(dāng)前流對(duì)象中包含的元素?cái)?shù)量。

Java代碼

longstartsWithB?=

stringCollection

.stream()

.filter((s)?->?s.startsWith("b"))

.count();

System.out.println(startsWithB);//?3

Reduce

該操作是一個(gè)終結(jié)操作稿饰,它能夠通過某一個(gè)方法杀赢,對(duì)元素進(jìn)行削減操作。該操作的結(jié)果會(huì)放在一個(gè)Optional變量里返回湘纵。

Java代碼

Optional?reduced?=

stringCollection

.stream()

.sorted()

.reduce((s1,?s2)?->?s1?+"#"+?s2);

reduced.ifPresent(System.out::println);

//?"aaa1#aaa2#bbb1#bbb2#bbb3#ccc#ddd1#ddd2"

Parallel Streams

像上面所說的,流操作可以是順序的滤淳,也可以是并行的梧喷。順序操作通過單線程執(zhí)行,而并行操作則通過多線程執(zhí)行脖咐。

下面的例子就演示了如何使用并行流進(jìn)行操作來提高運(yùn)行效率铺敌,代碼非常簡(jiǎn)單。

首先我們創(chuàng)建一個(gè)大的list屁擅,里面的元素都是唯一的:

Java代碼

intmax?=1000000;

List?values?=newArrayList<>(max);

for(inti?=0;?i?<?max;?i++)?{

UUID?uuid?=?UUID.randomUUID();

values.add(uuid.toString());

}

現(xiàn)在偿凭,我們測(cè)量一下對(duì)這個(gè)集合進(jìn)行排序所使用的時(shí)間。

順序排序

Java代碼

longt0?=?System.nanoTime();

longcount?=?values.stream().sorted().count();

System.out.println(count);

longt1?=?System.nanoTime();

longmillis?=?TimeUnit.NANOSECONDS.toMillis(t1?-?t0);

System.out.println(String.format("sequential?sort?took:?%d?ms",?millis));

//?sequential?sort?took:?899?ms

并行排序

Java代碼

longt0?=?System.nanoTime();

longcount?=?values.parallelStream().sorted().count();

System.out.println(count);

longt1?=?System.nanoTime();

longmillis?=?TimeUnit.NANOSECONDS.toMillis(t1?-?t0);

System.out.println(String.format("parallel?sort?took:?%d?ms",?millis));

//?parallel?sort?took:?472?ms

如你所見派歌,所有的代碼段幾乎都相同弯囊,唯一的不同就是把stream()改成了parallelStream(), 結(jié)果并行排序快了50%痰哨。

Map

正如前面已經(jīng)提到的那樣,map是不支持流操作的匾嘱。而更新后的map現(xiàn)在則支持多種實(shí)用的新方法斤斧,來完成常規(guī)的任務(wù)。

Java代碼

Map?map?=newHashMap<>();

for(inti?=0;?i?<10;?i++)?{

map.putIfAbsent(i,"val"+?i);

}

map.forEach((id,?val)?->?System.out.println(val));

上面的代碼風(fēng)格是完全自解釋的:putIfAbsent避免我們將null寫入霎烙;forEach接受一個(gè)消費(fèi)者對(duì)象撬讽,從而將操作實(shí)施到每一個(gè)map中的值上。

下面的這個(gè)例子展示了如何使用函數(shù)來計(jì)算map的編碼:

Java代碼

map.computeIfPresent(3,?(num,?val)?->?val?+?num);

map.get(3);//?val33

map.computeIfPresent(9,?(num,?val)?->null);

map.containsKey(9);//?false

map.computeIfAbsent(23,?num?->"val"+?num);

map.containsKey(23);//?true

map.computeIfAbsent(3,?num?->"bam");

map.get(3);//?val33

接下來悬垃,我們將學(xué)習(xí)游昼,當(dāng)給定一個(gè)key值時(shí),如何把一個(gè)實(shí)例從對(duì)應(yīng)的key中移除:

Java代碼

map.remove(3,"val3");

map.get(3);//?val33

map.remove(3,"val33");

map.get(3);//?null

另一個(gè)有用的方法:

Java代碼

map.getOrDefault(42,"not?found");//?not?found

將map中的實(shí)例合并也是非常容易的:

Java代碼

map.merge(9,"val9",?(value,?newValue)?->?value.concat(newValue));

map.get(9);//?val9

map.merge(9,"concat",?(value,?newValue)?->?value.concat(newValue));

map.get(9);//?val9concat

合并操作先看map中是否沒有特定的key/value存在尝蠕,如果是烘豌,則把key/value存入map,否則merging函數(shù)就會(huì)被調(diào)用趟佃,對(duì)現(xiàn)有的數(shù)值進(jìn)行修改扇谣。

時(shí)間日期API

Java 8 包含了全新的時(shí)間日期API,這些功能都放在了java.time包下闲昭。新的時(shí)間日期API是基于Joda-Time庫(kù)開發(fā)的罐寨,但是也不盡相同。下面的例子就涵蓋了大多數(shù)新的API的重要部分序矩。

Clock

Clock提供了對(duì)當(dāng)前時(shí)間和日期的訪問功能鸯绿。Clock是對(duì)當(dāng)前時(shí)區(qū)敏感的,并可用于替代 System.currentTimeMillis()方法來獲取當(dāng)前的毫秒時(shí)間簸淀。當(dāng)前時(shí)間線上的時(shí)刻可以用Instance類來表示瓶蝴。Instance 也能夠用于創(chuàng)建原先的java.util.Date對(duì)象。

Java代碼

Clock?clock?=?Clock.systemDefaultZone();

longmillis?=?clock.millis();

Instant?instant?=?clock.instant();

Date?legacyDate?=?Date.from(instant);//?legacy?java.util.Date

Timezones

時(shí)區(qū)類可以用一個(gè)ZoneId來表示租幕。時(shí)區(qū)類的對(duì)象可以通過靜態(tài)工廠方法方便地獲取舷手。時(shí)區(qū)類還定義了一個(gè)偏移量,用來在當(dāng)前時(shí)刻或某時(shí)間與目標(biāo)時(shí)區(qū)時(shí)間之間進(jìn)行轉(zhuǎn)換劲绪。

Java代碼

System.out.println(ZoneId.getAvailableZoneIds());

//?prints?all?available?timezone?ids

ZoneId?zone1?=?ZoneId.of("Europe/Berlin");

ZoneId?zone2?=?ZoneId.of("Brazil/East");

System.out.println(zone1.getRules());

System.out.println(zone2.getRules());

//?ZoneRules[currentStandardOffset=+01:00]

//?ZoneRules[currentStandardOffset=-03:00]

LocalTime

本地時(shí)間類表示一個(gè)沒有指定時(shí)區(qū)的時(shí)間男窟,例如,10 p.m.或者17:30:15贾富,下面的例子會(huì)用上面的例子定義的時(shí)區(qū)創(chuàng)建兩個(gè)本地時(shí)間對(duì)象歉眷。然后我們會(huì)比較兩個(gè)時(shí)間,并計(jì)算它們之間的小時(shí)和分鐘的不同颤枪。

Java代碼

LocalTime?now1?=?LocalTime.now(zone1);

LocalTime?now2?=?LocalTime.now(zone2);

System.out.println(now1.isBefore(now2));//?false

longhoursBetween?=?ChronoUnit.HOURS.between(now1,?now2);

longminutesBetween?=?ChronoUnit.MINUTES.between(now1,?now2);

System.out.println(hoursBetween);//?-3

System.out.println(minutesBetween);//?-239

LocalTime是由多個(gè)工廠方法組成汗捡,其目的是為了簡(jiǎn)化對(duì)時(shí)間對(duì)象實(shí)例的創(chuàng)建和操作,包括對(duì)時(shí)間字符串進(jìn)行解析的操作畏纲。

Java代碼

LocalTime?late?=?LocalTime.of(23,59,59);

System.out.println(late);//?23:59:59

DateTimeFormatter?germanFormatter?=

DateTimeFormatter

.ofLocalizedTime(FormatStyle.SHORT)

.withLocale(Locale.GERMAN);

LocalTime?leetTime?=?LocalTime.parse("13:37",?germanFormatter);

System.out.println(leetTime);//?13:37

LocalDate

本地時(shí)間表示了一個(gè)獨(dú)一無(wú)二的時(shí)間扇住,例如:2014-03-11春缕。這個(gè)時(shí)間是不可變的,與LocalTime是同源的台囱。下面的例子演示了如何通過加減日淡溯,月,年等指標(biāo)來計(jì)算新的日期簿训。記住咱娶,每一次操作都會(huì)返回一個(gè)新的時(shí)間對(duì)象。

Java代碼

LocalDate?today?=?LocalDate.now();

LocalDate?tomorrow?=?today.plus(1,?ChronoUnit.DAYS);

LocalDate?yesterday?=?tomorrow.minusDays(2);

LocalDate?independenceDay?=?LocalDate.of(2014,?Month.JULY,4);

DayOfWeek?dayOfWeek?=?independenceDay.getDayOfWeek();

System.out.println(dayOfWeek);//?FRIDAYParsing?a?LocalDate?from?a?string?is?just?as?simple?as?parsing?a?LocalTime:

解析字符串并形成LocalDate對(duì)象强品,這個(gè)操作和解析LocalTime一樣簡(jiǎn)單膘侮。

Java代碼

DateTimeFormatter?germanFormatter?=

DateTimeFormatter

.ofLocalizedDate(FormatStyle.MEDIUM)

.withLocale(Locale.GERMAN);

LocalDate?xmas?=?LocalDate.parse("24.12.2014",?germanFormatter);

System.out.println(xmas);//?2014-12-24

LocalDateTime

LocalDateTime表示的是日期-時(shí)間。它將剛才介紹的日期對(duì)象和時(shí)間對(duì)象結(jié)合起來的榛,形成了一個(gè)對(duì)象實(shí)例琼了。LocalDateTime是不可變的,與LocalTime和LocalDate的工作原理相同夫晌。我們可以通過調(diào)用方法來獲取日期時(shí)間對(duì)象中特定的數(shù)據(jù)域雕薪。

Java代碼

LocalDateTime?sylvester?=?LocalDateTime.of(2014,?Month.DECEMBER,31,23,59,59);

DayOfWeek?dayOfWeek?=?sylvester.getDayOfWeek();

System.out.println(dayOfWeek);//?WEDNESDAY

Month?month?=?sylvester.getMonth();

System.out.println(month);//?DECEMBER

longminuteOfDay?=?sylvester.getLong(ChronoField.MINUTE_OF_DAY);

System.out.println(minuteOfDay);//?1439

如果再加上的時(shí)區(qū)信息,LocalDateTime能夠被轉(zhuǎn)換成Instance實(shí)例晓淀。Instance能夠被轉(zhuǎn)換成以前的java.util.Date對(duì)象所袁。

Java代碼

Instant?instant?=?sylvester

.atZone(ZoneId.systemDefault())

.toInstant();

Date?legacyDate?=?Date.from(instant);

System.out.println(legacyDate);//?Wed?Dec?31?23:59:59?CET?2014

格式化日期-時(shí)間對(duì)象就和格式化日期對(duì)象或者時(shí)間對(duì)象一樣。除了使用預(yù)定義的格式以外凶掰,我們還可以創(chuàng)建自定義的格式化對(duì)象燥爷,然后匹配我們自定義的格式。

Java代碼

DateTimeFormatter?formatter?=

DateTimeFormatter

.ofPattern("MMM?dd,?yyyy?-?HH:mm");

LocalDateTime?parsed?=?LocalDateTime.parse("Nov?03,?2014?-?07:13",?formatter);

String?string?=?formatter.format(parsed);

System.out.println(string);//?Nov?03,?2014?-?07:13

不同于java.text.NumberFormat懦窘,新的DateTimeFormatter類是不可變的前翎,也是線程安全的。

更多的細(xì)節(jié)畅涂,請(qǐng)看這里

Annotations

Java 8中的注解是可重復(fù)的港华。讓我們直接深入看看例子,弄明白它是什么意思午衰。

首先苹丸,我們定義一個(gè)包裝注解,它包括了一個(gè)實(shí)際注解的數(shù)組

Java代碼

@interfaceHints?{

Hint[]?value();

}

@Repeatable(Hints.class)

@interfaceHint?{

String?value();

}

只要在前面加上注解名:@Repeatable苇经,Java 8 允許我們對(duì)同一類型使用多重注解:

變體1:使用注解容器(老方法):

Java代碼

@Hints({@Hint("hint1"),@Hint("hint2")})

classPerson?{}

變體2:使用可重復(fù)注解(新方法):

Java代碼

@Hint("hint1")

@Hint("hint2")

classPerson?{}

使用變體2,Java編譯器能夠在內(nèi)部自動(dòng)對(duì)@Hint進(jìn)行設(shè)置宦言。這對(duì)于通過反射來讀取注解信息來說扇单,是非常重要的。

Java代碼

Hint?hint?=?Person.class.getAnnotation(Hint.class);

System.out.println(hint);//?null

Hints?hints1?=?Person.class.getAnnotation(Hints.class);

System.out.println(hints1.value().length);//?2

Hint[]?hints2?=?Person.class.getAnnotationsByType(Hint.class);

System.out.println(hints2.length);//?2

盡管我們絕對(duì)不會(huì)在Person類上聲明@Hints注解奠旺,但是它的信息仍然可以通過getAnnotation(Hints.class)來讀 取蜘澜。并且施流,getAnnotationsByType方法會(huì)更方便,因?yàn)樗x予了所有@Hints注解標(biāo)注的方法直接的訪問權(quán)限鄙信。

Java代碼

@Target({ElementType.TYPE_PARAMETER,?ElementType.TYPE_USE})

@interfaceMyAnnotation?{}

總結(jié)

Java 8編程指南就到此告一段落瞪醋。當(dāng)然,還有很多內(nèi)容需要進(jìn)一步研究和說明装诡。這就需要靠讀者您來對(duì)JDK 8進(jìn)行探究了银受,例如:Arrays.parallelSort, StampedLock和CompletableFuture等等 ———— 我這里只是舉幾個(gè)例子而已。

我希望這個(gè)博文能夠?qū)δ兴鶐椭徊桑蚕M喿x愉快宾巍。完整的教程源代碼放在了GitHub上。您可以盡情地fork渔伯,并請(qǐng)通過Twitter告訴我您的反饋顶霞。

原文鏈接:winterbe翻譯:ImportNew.com-黃小非

譯文鏈接:http://www.importnew.com/10360.html

------------------------------------------------------------------------------------------------------------------------------------

加快OpenJDK的開發(fā)速度:繼2014年3月份發(fā)布了java8之后,我們進(jìn)入下一個(gè)兩年的發(fā)布周期锣吼。 Java 9預(yù)計(jì)在2016年發(fā)布选浑,并且已經(jīng)公布了JEP(JDK改進(jìn)提議)中的前期列表。同時(shí)玄叠,我們已經(jīng)把一些新特性整理到了JSR(Java規(guī)范請(qǐng)求)百侧,還有提 出了一些希望包括在新版本中的其他特性。

這些重要的特性都包括在Jigsaw項(xiàng)目中谓罗。顯著的性能改善和期待已久的API包括:進(jìn)程API更新今膊,JSON將成為java.util的一部分,貨幣處理API對(duì)于想處在技術(shù)最前沿的你狐粱,可從這里獲得Java 9的初期版本舀寓。

被接受的特性

1. Jigsaw 項(xiàng)目;模塊化源碼

Jigsaw項(xiàng)目是為了模塊化Java代碼、將JRE分成可相互協(xié)作的組件肌蜻,這也是Java 9 眾多特色種的一個(gè)互墓。JEP是邁向Jigsaw四步中的第一步,它不會(huì)改變JRE和JDK的真實(shí)結(jié)構(gòu)蒋搜。JEP是為了模塊化JDK源代碼篡撵,讓編譯系統(tǒng)能夠模塊 編譯并在構(gòu)建時(shí)檢查模塊邊界。這個(gè)項(xiàng)目原本是隨Java 8發(fā)布的豆挽,但由于推遲育谬,所以將把它加到Java 9.

一旦它完成,它可能允許根據(jù)一個(gè)項(xiàng)目需求自定義組件從而減少rt.jar的大小帮哈。在JDK 7 和JDK 8的rt.jar包中有大約20,000個(gè)類膛檀,但有很多類在一些特定的環(huán)境里面并沒有被用到(即使在Java 8的緊湊分布特性中已經(jīng)包含了一部分解決方法也存在著類冗余)。這么做是為了能讓Java能夠容易應(yīng)用到小型計(jì)算設(shè)備(比如網(wǎng)絡(luò)設(shè)備)中,提高它的安全和 性能咖刃,同時(shí)也能讓開發(fā)者更容易構(gòu)建和維護(hù)這些類庫(kù)泳炉。

2. 簡(jiǎn)化進(jìn)程API

截止到目前,Java控制與管理系統(tǒng)進(jìn)程的能力是有限的嚎杨。舉個(gè)例子花鹅,現(xiàn)在為了簡(jiǎn)便獲取你程序的進(jìn)程PID,你要么調(diào)用本地程序要么要自己使用一些變通方案枫浙。更多的是刨肃,每個(gè)(系統(tǒng))平臺(tái)需要有一個(gè)不同實(shí)現(xiàn)來確保你能獲得正確的結(jié)果。

期望代碼能獲取LinuxPIDS自脯,現(xiàn)在是如下方式:

在Java 9中之景,可以變換成如下方式(支持所有的操作系統(tǒng)):

這次更新將會(huì)擴(kuò)展Java與操作系統(tǒng)的交互能力:新增一些新的直接明了的方法去處理PIDs,進(jìn)程名字和狀態(tài)以及枚舉多個(gè)JVM和進(jìn)程以及更多事情膏潮。

3. 輕量級(jí) JSON API

目前有多種處理JSON的Java工具锻狗,但JSON API 獨(dú)到之處在于JSON API將作為Java語(yǔ)言的一部分,輕量并且運(yùn)用Java 8的新特性焕参。它將放在java.util包里一起發(fā)布(但在JSR 353里面的JSON是用第三方包或者其他的方法處理的).

4. 錢和貨幣的API

在Java 8引進(jìn)了日期和時(shí)間的API之后, Java 9引入了新的貨幣API, 用以表示貨幣, 支持幣種之間的轉(zhuǎn)換和各種復(fù)雜運(yùn)算. 關(guān)于這個(gè)項(xiàng)目的具體情況, 請(qǐng)?jiān)L問https://github.com/JavaMoney,里面已經(jīng)給出了使用說明和示例, 以下是幾個(gè)重要的例子:

更多關(guān)于 JSR 354的內(nèi)容

5. 改善鎖爭(zhēng)用機(jī)制

鎖爭(zhēng)用是限制許多Java多線程應(yīng)用性能的瓶頸. 新的機(jī)制在改善Java對(duì)象監(jiān)視器的性能方面已經(jīng)得到了多種基準(zhǔn)(benchmark)的驗(yàn)證, 其中包括Volano. 測(cè)試中通訊服務(wù)器開放了海量的進(jìn)程來連接客戶端, 其中有很多連接都申請(qǐng)同一個(gè)資源, 以此模擬重負(fù)荷日常應(yīng)用.

通過諸如此類的壓力測(cè)試我們可以估算JVM的極限吞吐量(每秒的消息數(shù)量). JEP在22種不同的測(cè)試中都得到了出色的成績(jī), 新的機(jī)制如果能在Java 9中得到應(yīng)用的話, 應(yīng)用程序的性能將會(huì)大大提升.

關(guān)于JEP 143的更多內(nèi)容

6. 代碼分段緩存

Java 9的另一個(gè)性能提升來自于JIT(Just-in-time)編譯器. 當(dāng)某段代碼被大量重復(fù)執(zhí)行的時(shí)候, 虛擬機(jī)會(huì)把這段代碼編譯成機(jī)器碼(native code)并儲(chǔ)存在代碼緩存里面, 進(jìn)而通過訪問緩存中不同分段的代碼來提升編譯器的效率.

和原來的單一緩存區(qū)域不同的是, 新的代碼緩存根據(jù)代碼自身的生命周期而分為三種:

永駐代碼(JVM 內(nèi)置 / 非方法代碼)

短期代碼(僅在某些條件下適用的配置性(profiled)代碼)

長(zhǎng)期代碼(非配置性代碼)

緩存分段會(huì)在各個(gè)方面提升程序的性能, 比如做垃圾回收掃描的時(shí)候可以直接跳過非方法代碼(永駐代碼), 從而提升效率.

更多關(guān)于JEP 197的內(nèi)容

7. 智能Java編譯, 第二階段

智能Java編譯工具sjavac的第一階段開始于JEP 139這個(gè)項(xiàng)目, 用于在多核處理器上提升JDK的編譯速度. 現(xiàn)在這個(gè)項(xiàng)目已經(jīng)進(jìn)入第二階段(JEP 199), 目的是改進(jìn)sjavac并讓其成為取代目前JDK編譯工具javac的Java默認(rèn)的通用編譯工具.

其他值得期待的內(nèi)容:

8. HTTP 2.0客戶端

HTTP 2.0標(biāo)準(zhǔn)雖然還沒正式發(fā)布, 但是已經(jīng)進(jìn)入了最終審查階段, 預(yù)計(jì)可以在Java 9發(fā)布之前審查完畢.JEP 110將會(huì)重新定義并實(shí)現(xiàn)一個(gè)全新的Java HTTP客戶端, 用來取代現(xiàn)在的HttpURLConnection, 同時(shí)也會(huì)實(shí)現(xiàn)HTTP 2.0和網(wǎng)絡(luò)接口(原文websockets). 它現(xiàn)在還沒被JEP正式認(rèn)可但我們希望在Java 9中包含這一項(xiàng)目的內(nèi)容.

官方的HTTP 2.0 RFC(Request for Comments, 官方技術(shù)討論/會(huì)議記錄等等的一系列文檔記錄)預(yù)訂于2015年2月發(fā)布, 它是基于Google發(fā)布的SPDY(Speedy, 快速的)協(xié)議. 基于SPDY協(xié)議的網(wǎng)絡(luò)相對(duì)于基于HTTP 1.1協(xié)議的網(wǎng)絡(luò)有11.81%到47.7%之間的顯著提速, 現(xiàn)在已經(jīng)有瀏覽器實(shí)現(xiàn)了這個(gè)協(xié)議.

9. Kulla計(jì)劃: Java的REPL實(shí)現(xiàn)

這個(gè)取名為Kulla的項(xiàng)目最近宣布將于2015年4月整合測(cè)試, 雖然已經(jīng)不太有希望能趕上Java 9的發(fā)布, 但如果進(jìn)度快的話或許剛好能趕上. 現(xiàn)在Java并沒有來自官方的REPL(Read-Eval-Print-Loop)方式, 也就是說現(xiàn)在如果你想要跑幾行Java代碼做一個(gè)快速的測(cè)試, 你仍然需要把這幾行代碼封裝在項(xiàng)目或者方法里面. 雖然在一些流行的IDE里面有Java REPL工具, 但它們并沒有官方支持, 而Kulla項(xiàng)目或許就能成為Java官方發(fā)布的REPL解決方案.

更多關(guān)于Kulla計(jì)劃的內(nèi)容

這些新功能出自何處轻纪?

JEP和JSR并不是無(wú)中生有,下面就介紹一下Java發(fā)展的生態(tài)環(huán)境:

小組- 對(duì)特定技術(shù)內(nèi)容, 比如安全叠纷、網(wǎng)絡(luò)刻帚、Swing、HotSpot涩嚣、有共同興趣的組織和個(gè)人崇众。

項(xiàng)目- 編寫代碼, 文檔以及其他工作,至少由一個(gè)小組贊助和支持航厚,比如最近的Lambda計(jì)劃顷歌,Jigsaw計(jì)劃和Sumatra計(jì)劃。

JDK改進(jìn)提案(JEP)- 每當(dāng)需要有新的嘗試的時(shí)候, JEP可以在JCP(Java Community Process)之前或者同時(shí)提出非正式的規(guī)范(specification)幔睬,被正是認(rèn)可的JEP正式寫進(jìn)JDK的發(fā)展路線圖并分配版本號(hào)眯漩。

Java規(guī)范提案(JSR)- 新特性的規(guī)范出現(xiàn)在這一個(gè)階段,可以來自于小組 / 項(xiàng)目麻顶、JEP赦抖、 JCP成員或者Java社區(qū)(community)成員的提案,每個(gè)Java版本都由相應(yīng)的JSR支持, Java 9暫時(shí)還沒有辅肾。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末队萤,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子矫钓,更是在濱河造成了極大的恐慌要尔,老刑警劉巖交胚,帶你破解...
    沈念sama閱讀 218,941評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異盈电,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)杯活,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門匆帚,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人旁钧,你說我怎么就攤上這事吸重。” “怎么了歪今?”我有些...
    開封第一講書人閱讀 165,345評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵嚎幸,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我寄猩,道長(zhǎng)嫉晶,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,851評(píng)論 1 295
  • 正文 為了忘掉前任田篇,我火速辦了婚禮替废,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘泊柬。我一直安慰自己椎镣,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,868評(píng)論 6 392
  • 文/花漫 我一把揭開白布兽赁。 她就那樣靜靜地躺著状答,像睡著了一般。 火紅的嫁衣襯著肌膚如雪刀崖。 梳的紋絲不亂的頭發(fā)上惊科,一...
    開封第一講書人閱讀 51,688評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音蒲跨,去河邊找鬼译断。 笑死,一個(gè)胖子當(dāng)著我的面吹牛或悲,可吹牛的內(nèi)容都是我干的孙咪。 我是一名探鬼主播,決...
    沈念sama閱讀 40,414評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼巡语,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼翎蹈!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起男公,我...
    開封第一講書人閱讀 39,319評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤荤堪,失蹤者是張志新(化名)和其女友劉穎合陵,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體澄阳,經(jīng)...
    沈念sama閱讀 45,775評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡拥知,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了碎赢。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片低剔。...
    茶點(diǎn)故事閱讀 40,096評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖肮塞,靈堂內(nèi)的尸體忽然破棺而出襟齿,到底是詐尸還是另有隱情,我是刑警寧澤枕赵,帶...
    沈念sama閱讀 35,789評(píng)論 5 346
  • 正文 年R本政府宣布猜欺,位于F島的核電站,受9級(jí)特大地震影響拷窜,放射性物質(zhì)發(fā)生泄漏开皿。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,437評(píng)論 3 331
  • 文/蒙蒙 一装黑、第九天 我趴在偏房一處隱蔽的房頂上張望副瀑。 院中可真熱鬧,春花似錦恋谭、人聲如沸糠睡。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)狈孔。三九已至,卻和暖如春材义,著一層夾襖步出監(jiān)牢的瞬間均抽,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評(píng)論 1 271
  • 我被黑心中介騙來泰國(guó)打工其掂, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留油挥,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,308評(píng)論 3 372
  • 正文 我出身青樓款熬,卻偏偏與公主長(zhǎng)得像深寥,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子贤牛,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,037評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • 原鏈接:http://www.cnblogs.com/langtianya/p/3757993.html JDK各...
    把愛放下會(huì)走更遠(yuǎn)閱讀 1,112評(píng)論 0 10
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理惋鹅,服務(wù)發(fā)現(xiàn),斷路器殉簸,智...
    卡卡羅2017閱讀 134,659評(píng)論 18 139
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語(yǔ)法闰集,類相關(guān)的語(yǔ)法沽讹,內(nèi)部類的語(yǔ)法,繼承相關(guān)的語(yǔ)法武鲁,異常的語(yǔ)法爽雄,線程的語(yǔ)...
    子非魚_t_閱讀 31,639評(píng)論 18 399
  • (一)Java部分 1、列舉出JAVA中6個(gè)比較常用的包【天威誠(chéng)信面試題】 【參考答案】 java.lang;ja...
    獨(dú)云閱讀 7,107評(píng)論 0 62
  • 我愛你姣好的面容 不愛你臉上的粉底 我愛你如烈焰的紅唇 不愛你唇上的那抹紅 我愛你曼妙的曲線 不愛你穿的加厚文胸 ...
    慵懶小獸閱讀 244評(píng)論 0 0