JAVA JDK1.5-1.9新特性

1.5
1.自動裝箱與拆箱:
2.枚舉(經常使用來設計單例模式)
3.靜態導入
4.可變參數
5.內省

1.6
1.Web服務元數據
2.腳本語言支持
3.JTable的排序和過濾
4.更簡單,更強大的JAX-WS
5.輕量級Http Server
6.嵌入式數據庫 Derby

1.7
1,switch中可使用字串了
2.運用List tempList = new ArrayList<>(); 即泛型實例化類型自動推斷
3.語法上支持集合,而不必定是數組
4.新增一些取環境信息的工具方法
5.Boolean類型反轉,空指針安全,參與位運算
6.兩個char間的equals
7.安全的加減乘除
8.map集合支持併發請求,且能夠寫成 Map map = {name:"xxx",age:18};

1.8
1. 容許在接口中有默認方法實現
2. Lambda表達式
3. 函數式接口
4. 方法和構造函數引用
5. Lambda的範圍
6. 內置函數式接口
7. Streams
8. Parallel Streams
9. Map
10. 時間日期API
11. Annotations

1.9
1. Jigsaw 項目;模塊化源碼
2. 簡化進程API
3. 輕量級 JSON API
4. 錢和貨幣的API
5. 改善鎖爭用機制
6. 代碼分段緩存
7. 智能Java編譯, 第二階段
8. HTTP 2.0客戶端
9. Kulla計劃: Java的REPL實現html

 

---------------------------------------------------------------------------java

JDK1.5新特性:git

1自動裝箱與拆箱程序員

Integer iObj = 3;github

System.out.println(iObj + 12);
   Integer i1 = 137(-128--127範圍時,爲true);
   Integer i2 = 137(-128--127範圍時,爲true);web

   System.out.println(i1 == i2); //false,可是括號中時卻返回ture,緣由是Integer採用的是享元模式正則表達式

   Integer i3 = Integer.valueOf(213);
   Integer i4 = Integer.valueOf(213);
   System.out.println(i3==i4);//同上,另外一種包裝形式數據庫

 

枚舉apache

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 靜態導入

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

可變參數

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

}

內省

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服務元數據

Java 裏的Web服務元數據跟微軟的方案基本沒有語義上的區別,自從JDK5添加了元數據功能(Annotation)以後,SUN幾乎重構了整個J2EE體 系, 因爲變化很大,乾脆將名字也重構爲Java EE, Java EE(當前版本爲5.0)將元數據歸入不少規範當中,這其中就包括Web Services的相關規範, 加入元數據以後的Web Services服務器端編程模型就跟上面看到的C#片段差很少了, 這顯然比之前的JAX-RPC編程模型簡單(固然, Axis的編程模型也很簡單).這裏要談的Web服務元數據(JSR 181)只是Java Web 服務規範中的一個,它跟Common Annotations, JAXB2, StAX, SAAJ和JAX-WS等共同構成Java EE 5的Web Services技術堆棧.

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中相關的描述    
     @WebMethod
     public String sayHi(@WebParam(name="MyName") String name){
         return "Hi,"+name; //@WebParam是自定義參數name在WSDL中相關的描述
     }    
     @Oneway //代表該服務方法是單向的,既沒有返回值,也不該該聲明檢查異常
     @WebMethod(action="printSystemTime",operationName="printSystemTime")//自定義該方法在WSDL中相關的描述
     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() {
             //發佈WSProvider到http://localhost:8888/chinajash/WSProvider這個地址,以前必須調用wsgen命令
             //生成服務類WSProvider的支持類,命令以下:
             //wsgen -cp . WebServices.WSProvider
             Endpoint.publish("http://localhost:8888/chinajash/WSProvider",new WSProvider());
         }        
     }
}

若是想看到Web Services Engine生成的WSDL文件是否遵照上面的元數據, 咱們沒有必要將上面的WSProvider部署到支持JSR-181的應用服務器或Servlet形式的Web Services Engine,如今JDK6已經提供了一個很簡單的機制能夠用來測試和發佈Web Services,下面講講如何在JDK6環境下發布Web Services和查看生成的WSDL
1.將/bin加入path環境變量
2.在命令行下切換當前目錄到WSProvider的class文件所在的目錄,運行下面命令
wsgen -cp . WebServices.WSProvider
在這個例子中會生成如下3個類的源代碼文件及class文件
SayHi
SayHiResponse
PrintTime
3.執行以下代碼發佈WSProvider到http://localhost:8888/chinajash/WSProvider,在這裏能夠執行WSProvider類的main方法就能夠
Endpoint.publish("http://localhost:8888/chinajash/WSProvider",new WSProvider());
4.在瀏覽器輸入http://localhost:8888/chinajash/WSProvider?wsdl就能夠看到生成的WSDL文件,爲了節省篇幅,這裏就不把生成的WSDL文件貼上了,你們能夠本身動手試試.
2.腳本語言支持

JDK6增長了對腳本語言的支持(JSR 223), 原理上是將腳本語言編譯成bytecode,這樣腳本語言也能享用Java平臺的諸多優點,包括可移植性,安全等,另外,因爲如今是編譯成 bytecode後再執行,因此比原來邊解釋邊執行效率要高不少。加入對腳本語言的支持後,對Java語言也提供瞭如下好處。
一、許多腳本語言都有動態特性,好比,你不須要用一個變量以前先聲明它,你能夠用一個變量存放徹底不一樣類型的對象,你不須要作強制類型轉換,由於轉換都是自動的。如今Java語言也能夠經過對腳本語言的支持間接得到這種靈活性。
二、 能夠用腳本語言快速開發產品原型,由於如今能夠Edit-Run,而無需Edit-Compile-Run,固然,由於Java有很是好的IDE支持,我 們徹底能夠在IDE裏面編輯源文件,而後點擊運行(隱含編譯),以此達到快速開發原型的目的,因此這點好處基本上能夠忽略。
三、經過引入腳本語言能夠輕鬆實現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類,它是使用Scripting API的入口,ScriptEngineManager能夠經過jar服務發現(service discovery)機制尋找合適的腳本引擎類(ScriptEngine),使用Scripting API的最簡單方式只需下面三步
一、建立一個ScriptEngineManager對象
二、經過ScriptEngineManager得到ScriptEngine對象
三、用ScriptEngine的eval方法執行腳本

下面是一個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     }     }運行上面程序,控制檯會輸出Hello, Scripting上面這個簡單的Scripting程序演示瞭如何在Java裏面運行腳本語言,除此以外,咱們還能夠利用Scripting API實現如下功能一、暴露Java對象爲腳本語言的全局變量二、在Java中調用腳本語言的方法三、腳本語言能夠實現Java的接口四、腳本語言能夠像Java同樣使用JDK平臺下的類下面的類演示了以上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對象爲腳本語言的全局變量          testInvokeScriptMethod(engine);//演示如何在Java中調用腳本語言的方法          testScriptInterface(engine);//演示腳本語言如何實現Java的接口          testUsingJDKClasses(engine);//演示腳本語言如何使用JDK平臺下的類     }         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是腳本語言裏的一個全局變量,專用於訪問JDK的package         String js = "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中有一個命令行工具??jrunscript,你能夠在/bin下面找到這個工 具,jrunscript是一個腳本語言的解釋程序,它獨立於腳本語言,但默認是用JavaScript,咱們能夠用jrunscript來測試本身寫的 腳本語言是否正確,下面是一個在命令行運行jrunscript的簡單例子
jrunscript
js>println("Hello,JrunScript");
Hello,JrunScript
js>9*8
72.0
js>
3.JTable的排序和過濾

原來的JTable基本上是隻能顯示數據,在JDK6新增了對JTable的排序和過濾功能,下面代碼演示了這兩個功能


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設置排序器
        
         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設置基於正則表達式的過濾條件
                 }
             }
         });
        
         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);
     }

運行上面程序,單擊JTable的某一個title,這個title對應的列就會按照升序/降序從新排列;在下面的Criteria文本框中輸入"ese",點擊"Do Filter"按鈕,JTable將只顯示帶有"ese"字符串的行,也就是China和Japan兩行,若是文本框裏面什麼都沒有,點擊"Do Filter"按鈕,這時JTable會顯示全部的行。
4.更簡單,更強大的JAX-WS

JAX-WS2.0的來歷

--------------------------------------------------------------------------------
JAX-WS(JSR-224) 是Java Architecture for XML Web Services的縮寫,簡單說就是一種用Java和XML開發Web Services應用程序的框架, 目前版本是2.0, 它是JAX-RPC 1.1的後續版本, J2EE 1.4帶的就是JAX-RPC1.1, 而Java EE 5裏面包括了JAX-WS 2.0,但爲了向後兼容,仍然支持JAX-RPC. 如今,SUN又把JAX-WS直接放到了Java SE 6裏面,因爲JAX-WS會用到Common Annotation(JSR 250),Java Web Services Metadata(JSR 181), JAXB2(JSR 222), StAX(JSR 173), 因此SUN也必須把後幾個原屬於Java EE範疇的Components下放到Java SE, 如今咱們能夠清楚地理解了爲何Sun要把這些看似跟Java SE沒有關係的Components放進來,終極目的就是要在Java SE裏面支持Web Services.

JAX-WS2.0的架構

--------------------------------------------------------------------------------
JAX-WS不是一個孤立的框架,它依賴於衆多其餘的規範,本質上它由如下幾部分組成
1.用來開發Web Services的Java API
2.用來處理Marshal/Unmarshal的XML Binding機制,JAX-WS2.0用JAXB2來處理Java Object與XML之間的映射,Marshalling就是把Java Object映射到XML,Unmarshalling則是把XML映射到Java Object.之因此要作Java Object與XML的映射,是由於最終做爲方法參數和返回值的Java Object要經過網絡傳輸協議(通常是SOAP)傳送,這就要求必須對Java Object作相似序列化和反序列化的工做,在SOAP中就是要用XML來表示Java object的內部狀態
3.衆多元數據(Annotations)會被JAX-WS用來描述Web Services的相關類,包括Common Annotations, Web Services Metadata, JAXB2的元數據和JAX-WS2.0規範本身的元數據.
4.Annotation Processing Tool(APT) 是JAX-WS重要的組成部分,因爲JAX-WS2.0規範用到不少元數據,因此須要APT來處理衆多的Annotations. 在/bin下有兩個命令wsgen和wsimport,就是用到APT和Compiler API來處理碰到的Annotations,wsgen能夠爲Web Services Provider產生並編譯必要的幫助類和相關支持文件,wsimport以WSDL做爲輸入爲Web Service Consumer產生並編譯必要的幫助類和相關支持文件.
5.JAX-WS還包括JAX-WS Runtime與應用服務器和工具之間的契約關係

JAX-WS2.0的編程模型

--------------------------------------------------------------------------------
如今用JAX-WS2.0來編寫Web Services很是簡單,不像JAX-RPC,JAX-WS能夠把任意POJO暴露爲Web Services,服務類不須要實現接口,服務方法也沒有必要拋出RMI異常.下面介紹在JDK6環境下用JAX-WS2.0開發和測試Web Services的步驟
1.編寫服務類,並用Web Services Metadata(JSR-181)標註這個服務類,我用個人另外一篇BlogJDK6的新特性之十:Web服務元數據中的WSProvider類做爲服務類的例子,在此我重複貼一下WSProvider類的源代碼:

@WebService(targetNamespace="http://blog.csdn.net/chinajash",serviceName="HelloService")
public class WSProvider {
     @WebResult(name="Greetings")//自定義該方法返回值在WSDL中相關的描述    
     @WebMethod
     public String sayHi(@WebParam(name="MyName") String name){
         return "Hi,"+name; //@WebParam是自定義參數name在WSDL中相關的描述
     }    
     @Oneway //代表該服務方法是單向的,既沒有返回值,也不該該聲明檢查異常
     @WebMethod(action="printSystemTime",operationName="printSystemTime")//自定義該方法在WSDL中相關的描述
     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() {
             //發佈WSProvider到http://localhost:8888/chinajash/WSProvider這個地址,以前必須調用wsgen命令
             //生成服務類WSProvider的支持類,命令以下:
             //wsgen -cp . WebServices.WSProvider
             Endpoint.publish("http://localhost:8888/chinajash/WSProvider",new WSProvider());
         }        
     }
}
2.用wsgen生成上面服務類的必要的幫助類,而後調用用EndPoint類的靜態方法publish發佈服務類(步驟請參考個人另外一篇Blog JDK6的新特性之十:Web服務元數據),我在這裏是將服務類發佈到http://localhost:8888/chinajash/WSProvider
3.用wsimport爲服務消費者(也就是服務的客戶端)生成必要的幫助類,命令以下:
wsimport http://localhost:8888/chinajash/WSProvider?wsdl
這會在<當前目錄>\net\csdn\blog\chinajash下生成客戶端的幫助類,在這個例子中會生成7個類
HelloService.class
ObjectFactory.class
package-info.class
PrintSystemTime.class
SayHi.class
SayHiResponse.class
WSProvider.class
4.在客戶端用下面代碼便可調用步驟1定義的Web Service
HelloService hs = new HelloService();
WSProvider ws = hs.getWSProviderPort();
System.out.println(ws.sayHi("chinajash"));
ws.printSystemTime();
調用上述代碼後客戶端控制檯輸出
hi,chinajash
服務端控制檯輸出服務器當前系統時間
5.輕量級Http Server

JDK6的新特性之五:輕量級Http Server

JDK6提供了一個簡單的Http Server API,據此咱們能夠構建本身的嵌入式Http Server,它支持Http和Https協議,提供了HTTP1.1的部分實現,沒有被實現的那部分能夠經過擴展已有的Http Server API 來實現,程序員必須本身實現HttpHandler接口,HttpServer會調用HttpHandler實現類的回調方法來處理客戶端請求,在這裏, 咱們把一個Http請求和它的響應稱爲一個交換,包裝成HttpExchange類,HttpServer負責將HttpExchange傳給 HttpHandler實現類的回調方法.下面代碼演示了怎樣建立本身的Http Server


public class HTTPServerAPITester {
     public static void main(String[] args) {
         try {
             HttpServer hs = HttpServer.create(new InetSocketAddress(8888),0);//設置HttpServer的端口爲8888
             hs.createContext("/chinajash", new MyHandler());//用MyHandler類內處理到/chinajash的請求
             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();
    }
}

運行程序後,在瀏覽器內輸入http://localhost:8888/xx,瀏覽器輸出
6.嵌入式數據庫 Derby

Derby是IBM送給開源社區的又一個禮物,是一個pure java的數據庫,如今已經被列入到java1.6中。
不知道對於大數據量的性能如何,但傳說中啓動derby只會給JVM添加2M的內存,對那些小數據庫應用,好比像用access那種應該是挺有誘惑力的。
另外,麻雀雖小,五臟俱全,功能要比access多得多咯,包括事務處理,併發,觸發器都有,管理又簡單,所以本身用來作點工具正好合適。
廢話少說,介紹一下我折騰了半天的經驗吧。
個人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,把兩個插件安裝到eclipse上
2,打開ecllipse,新建一個project
3,右鍵這個project,選擇Apache Derby,再選擇add apache derby native,發現只是給個人project添加了幾個derby的jar,還不是在我看着順眼的lib目錄裏,索性幹掉,換上db-derby- 10.1.3.1-bin.tar.gz解壓出來之後lib目錄下的jar文件,在Build Path裏設置一下;
4,右鍵Project,在apache derby裏選擇start apache derby network server,控制檯能夠看到derby啓動後打出的「服務器準備在端口 1527 上接受鏈接。」
5,右鍵Project,在apache derby裏選擇ij(Interactive SQL),啓動SQL控制檯;
6,輸入connect jdbc:derby:testdb;create=true; 注意要有單引號,能夠在工程跟目錄下建立testdb數據庫,能夠看到一個新建的目錄testdb,那裏的文件就是數據庫咯;
7,用標準的SQL語句來建一個數據庫試試:
create table test (a varchar(4) not null, b char(2) primary key);
竟然能夠用,太神奇了,呵呵
8,再插入一條語句試試呢,insert into test(a,b) values(a,11);,嗯,不錯,能夠用select 查出來的哦。
9,再插一下:insert into test(a,b) values(a,11);,哦哦,報錯了,「錯誤 23505:語句異常終止,由於它致使「TEST」上所定義的「SQL060710092132480」標識的惟一或主鍵約束或惟一索引中出現重複鍵值。」 呵呵。
10,好了,如今能夠像你控制的其餘數據庫同樣來控制Derby了。


若是上述方法不行,或者你習慣了在eclipse以外使用和管理數據庫,那麼能夠很方便的把Derby「裝」在系統裏。下面我說一下步驟:
1,把db-derby-10.1.3.1-bin.tar.gz解壓到c:\derby,使lib和framework兩個目錄在c:\derby下邊便可
2,設置環境變量

設置一個c:\derby\framework\embeded\bin或c:\derby\framework\NetworkServe\bin到Path中,這樣咱們就能夠直接執行上邊介紹的connect這樣的命令而不用每次鑽到那個目錄下去執行了 
設置c:\derby\lib\derby.jar;c:\derby\lib\derbytoos.jar到CLASSPATH中,以便讓這些java編成的命令可以正確執行;
3,打開cmd
4,敲入startNetworkServer,能夠看到像在eclisp中提示的那樣啓動了server
5,再打開一個cmd,敲入sysinfo,能夠看到derby的環境信息了,注意在java user dir這一項,也許是java用戶目錄上和上邊看到的會有所不一樣哦,這樣在connect jdbc:derby:testdb;create=true;的建的數據庫目錄就不同咯。
6,敲入ij,好了,進入到上邊的交互界面,能夠建一個數據庫看看了。
7,最後在另一個cmd中敲入stopNetworkServer就能夠關閉數據庫了。

若是你兩種方法都試過了,那麼須要注意的,仍是上邊步驟5的問題,這個問題是你可能隨時會啓動一個數據庫或新建一個數據庫,但若是你剛剛使用derby,你可能尚未察覺。
derby實際上有兩種啓動方式,一種是嵌入式的,一種是網絡服務器的啓動。
1,咱們在eclipse中右鍵start apache derby network server那個,就是網絡服務器的啓動方式,在這種方式下能夠用另一臺計算機在ij中以:
connect jdbc:derby://192.168.0.28:1527/testdb 
的方式進行連接。
2,第二種啓動方式是在ij裏邊就直接
connect jdbc:derby:testdb
這實際是在連當前配置環境下java user dir下那個目錄的數據庫。

看到這裏可能有點糊塗了,這麼就會出問題了那?
實際上derby的訪問更像是一種使用derby driver對本地文件系統的訪問,無論啓動不啓動網絡服務器,均可以用driver訪問本地的數據庫。這樣,在ij裏邊像第二種方式那樣創建鏈接是徹底能夠的。啓動了網絡服務器,只不過是可以讓其餘主機訪問罷了。

另一個問題是,在eclipse中和在系統中鏈接服務器,在connect的時候這個當前配置環境是不同的,eclipse默認工程所在路徑是數據庫的所在路徑,而在系統中「裝」derby則會認爲 c:\document and settings下邊那個用戶目錄是數據庫的所在路徑。
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.運用List tempList = new ArrayList<>(); 即泛型實例化類型自動推斷
3.語法上支持集合,而不必定是數組

final List piDigits = [ 1,2,3,4,5,8 ];   
4.新增一些取環境信息的工具方法

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

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

File System.getUserHomeDir() // 當前用戶目錄

File System.getUserDir() // 啓動java進程時所在的目錄5

5.Boolean類型反轉,空指針安全,參與位運算

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.兩個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集合支持併發請求,且能夠寫成 Map map = {name:"xxx",age:18};

 

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

 

java1.8新特性

容許在接口中有默認方法實現 Top

Java 8 容許咱們使用default關鍵字,爲接口聲明添加非抽象的方法實現。這個特性又被稱爲擴展方法。下面是咱們的第一個例子:

Java代碼
  1. interface Formula {  
  2.     double calculate(int a);  
  3.    
  4.     default double sqrt(int a) {  
  5.         return Math.sqrt(a);  
  6.     }  
  7. }  

在接口Formula中,除了抽象方法caculate之外,還定義了一個默認方法sqrt。Formula的實現類只須要實現抽象方法caculate就能夠了。默認方法sqrt能夠直接使用。

Java代碼
  1. Formula formula = new Formula() {  
  2.     @Override  
  3.     public double calculate(int a) {  
  4.         return sqrt(a * 100);  
  5.     }  
  6. };  
  7.    
  8. formula.calculate(100);     // 100.0  
  9. formula.sqrt(16);           // 4.0  

formula對象以匿名對象的形式實現了Formula接口。代碼很囉嗦:用了6行代碼才實現了一個簡單的計算功能:a*100開平方根。咱們在下一節會看到,Java 8 還有一種更加優美的方法,可以實現包含單個函數的對象。

Lambda表達式 Top

讓咱們從最簡單的例子開始,來學習如何對一個string列表進行排序。咱們首先使用Java 8以前的方法來實現:

Java代碼
  1. List names = Arrays.asList("peter", "anna", "mike", "xenia");  
  2.    
  3. Collections.sort(names, new Comparator() {  
  4.     @Override  
  5.     public int compare(String a, String b) {  
  6.         return b.compareTo(a);  
  7.     }  
  8. });  

靜態工具方法Collections.sort接受一個list,和一個Comparator接口做爲輸入參數,Comparator的實現類可 以對輸入的list中的元素進行比較。一般狀況下,你能夠直接用建立匿名Comparator對象,並把它做爲參數傳遞給sort方法。

除了建立匿名對象之外,Java 8 還提供了一種更簡潔的方式,Lambda表達式。

Java代碼
  1. Collections.sort(names, (String a, String b) -> {  
  2.     return b.compareTo(a);  
  3. });  

你能夠看到,這段代碼就比以前的更加簡短和易讀。可是,它還能夠更加簡短:

Java代碼
  1. Collections.sort(names, (String a, String b) -> b.compareTo(a));  

只要一行代碼,包含了方法體。你甚至能夠連大括號對{}和return關鍵字都省略不要。不過這還不是最短的寫法:

Java代碼
  1. Collections.sort(names, (a, b) -> b.compareTo(a));  

Java編譯器可以自動識別參數的類型,因此你就能夠省略掉類型不寫。讓咱們再深刻地研究一下lambda表達式的威力吧。

函數式接口 Top

Lambda表達式如何匹配Java的類型系統?每個lambda都可以經過一個特定的接口,與一個給定的類型進行匹配。一個所謂的函數式接口必需要有 且僅有一個抽象方法聲明。每一個與之對應的lambda表達式必需要與抽象方法的聲明相匹配。因爲默認方法不是抽象的,所以你能夠在你的函數式接口裏任意添 加默認方法。

任意只包含一個抽象方法的接口,咱們均可以用來作成lambda表達式。爲了讓你定義的接口知足要求,你應當在接口前加上@FunctionalInterface 標註。編譯器會注意到這個標註,若是你的接口中定義了第二個抽象方法的話,編譯器會拋出異常。

舉例:

Java代碼
  1. @FunctionalInterface  
  2. interface Converter {  
  3.     T convert(F from);  
  4. }  
  5.    
  6. Converter converter = (from) -> Integer.valueOf(from);  
  7. Integer converted = converter.convert("123");  
  8. System.out.println(converted);    // 123  

注意,若是你不寫@FunctionalInterface 標註,程序也是正確的。


方法和構造函數引用 Top

上面的代碼實例能夠經過靜態方法引用,使之更加簡潔:

Java代碼
  1. Converter converter = Integer::valueOf;  
  2. Integer converted = converter.convert("123");  
  3. System.out.println(converted);   // 123  

Java 8 容許你經過::關鍵字獲取方法或者構造函數的的引用。上面的例子就演示瞭如何引用一個靜態方法。並且,咱們還能夠對一個對象的方法進行引用:

Java代碼
  1. class Something {  
  2.     String startsWith(String s) {  
  3.         return String.valueOf(s.charAt(0));  
  4.     }  
  5. }  
  6.    
  7. Something something = new Something();  
  8. Converter converter = something::startsWith;  
  9. String converted = converter.convert("Java");  
  10. System.out.println(converted);    // "J"  

讓咱們看看如何使用::關鍵字引用構造函數。首先咱們定義一個示例bean,包含不一樣的構造方法:

Java代碼
  1. class Person {  
  2.     String firstName;  
  3.     String lastName;  
  4.    
  5.     Person() {}  
  6.    
  7.     Person(String firstName, String lastName) {  
  8.         this.firstName = firstName;  
  9.         this.lastName = lastName;  
  10.     }  
  11. }  

接下來,咱們定義一個person工廠接口,用來建立新的person對象:

Java代碼
  1. interface PersonFactoryextends Person> {  
  2.     P create(String firstName, String lastName);  
  3. }  

而後咱們經過構造函數引用來把全部東西拼到一塊兒,而不是像之前同樣,經過手動實現一個工廠來這麼作。

Java代碼
  1. PersonFactory personFactory = Person::new;  
  2. Person person = personFactory.create("Peter", "Parker");  

咱們經過Person::new來建立一個Person類構造函數的引用。Java編譯器會自動地選擇合適的構造函數來匹配PersonFactory.create函數的簽名,並選擇正確的構造函數形式。


Lambda的範圍 Top

對於lambdab表達式外部的變量,其訪問權限的粒度與匿名對象的方式很是相似。你可以訪問局部對應的外部區域的局部final變量,以及成員變量和靜態變量。

訪問局部變量

咱們能夠訪問lambda表達式外部的final局部變量:

Java代碼
  1. final int num = 1;  
  2. Converter stringConverter =  
  3.         (from) -> String.valueOf(from + num);  
  4.    
  5. stringConverter.convert(2);     // 3  

可是與匿名對象不一樣的是,變量num並不須要必定是final。下面的代碼依然是合法的:

Java代碼
  1. int num = 1;  
  2. Converter stringConverter =  
  3.         (from) -> String.valueOf(from + num);  
  4.    
  5. stringConverter.convert(2);     // 3  

然而,num在編譯的時候被隱式地當作final變量來處理。下面的代碼就不合法:

Java代碼
  1. int num = 1;  
  2. Converter stringConverter =  
  3.         (from) -> String.valueOf(from + num);  
  4. num = 3;  

在lambda表達式內部企圖改變num的值也是不容許的。

訪問成員變量和靜態變量

與局部變量不一樣,咱們在lambda表達式的內部能獲取到對成員變量或靜態變量的讀寫權。這種訪問行爲在匿名對象裏是很是典型的。

Java代碼
  1. class Lambda4 {  
  2.     static int outerStaticNum;  
  3.     int outerNum;  
  4.    
  5.     void testScopes() {  
  6.         Converter stringConverter1 = (from) -> {  
  7.             outerNum = 23;  
  8.             return String.valueOf(from);  
  9.         };  
  10.    
  11.         Converter stringConverter2 = (from) -> {  
  12.             outerStaticNum = 72;  
  13.             return String.valueOf(from);  
  14.         };  
  15.     }  
  16. }  

訪問默認接口方法

還記得第一節裏面formula的那個例子麼? 接口Formula定義了一個默認的方法sqrt,該方法可以訪問formula全部的對象實例,包括匿名對象。這個對lambda表達式來說則無效。

默認方法沒法在lambda表達式內部被訪問。所以下面的代碼是沒法經過編譯的:

Java代碼
  1. Formula formula = (a) -> sqrt( a * 100);  



內置函數式接口 Top

JDK 1.8 API中包含了不少內置的函數式接口。有些是在之前版本的Java中你們耳熟能詳的,例如Comparator接口,或者Runnable接口。對這些現 成的接口進行實現,能夠經過@FunctionalInterface 標註來啓用Lambda功能支持。

此外,Java 8 API 還提供了不少新的函數式接口,來下降程序員的工做負擔。有些新的接口已經在 Google Guava庫中頗有名了。若是你對這些庫很熟的話,你甚至閉上眼睛都可以想到,這些接口在類庫的實現過程當中起了多麼大的做用。

Predicates

Predicate是一個布爾類型的函數,該函數只有一個輸入參數。Predicate接口包含了多種默認方法,用於處理複雜的邏輯動詞(and, or,negate):

Java代碼
  1. Predicate predicate = (s) -> s.length() > 0;  
  2.    
  3. predicate.test("foo");              // true  
  4. predicate.negate().test("foo");     // false  
  5.    
  6. Predicate nonNull = Objects::nonNull;  
  7. Predicate isNull = Objects::isNull;  
  8.    
  9. Predicate isEmpty = String::isEmpty;  
  10. Predicate isNotEmpty = isEmpty.negate();  

Functions

Function接口接收一個參數,並返回單一的結果。默認方法能夠將多個函數串在一塊兒(compse, andThen):

Java代碼
  1. Function toInteger = Integer::valueOf;  
  2. Function backToString = toInteger.andThen(String::valueOf);  
  3.    
  4. backToString.apply("123");     // "123"  

Suppliers

Supplier接口產生一個給定類型的結果。與Function不一樣的是,Supplier沒有輸入參數。

Java代碼
  1. Supplier personSupplier = Person::new;  
  2. personSupplier.get();   // new Person  

Consumers

Consumer表明了在一個輸入參數上須要進行的操做。

Java代碼
  1. Consumer greeter = (p) -> System.out.println("Hello, " + p.firstName);  
  2. greeter.accept(new Person("Luke", "Skywalker"));  

Comparators

Comparator接口在早期的Java版本中很是著名。Java 8 爲這個接口添加了不一樣的默認方法。

Java代碼
  1. Comparator comparator = (p1, p2) -> p1.firstName.compareTo(p2.firstName);  
  2.    
  3. Person p1 = new Person("John", "Doe");  
  4. Person p2 = new Person("Alice", "Wonderland");  
  5.    
  6. comparator.compare(p1, p2);             // > 0  
  7. comparator.reversed().compare(p1, p2);  // < 0  

Optionals

Optional不是一個函數式接口,而是一個精巧的工具接口,用來防止NullPointerEception產生。這個概念在下一節會顯得很重要,因此咱們在這裏快速地瀏覽一下Optional的工做原理。

Optional是一個簡單的值容器,這個值能夠是null,也能夠是non-null。考慮到一個方法可能會返回一個non-null的值,也可能返回一個空值。爲了避免直接返回null,咱們在Java 8中就返回一個Optional。

Java代碼
  1. Optional optional = Optional.of("bam");  
  2.    
  3. optional.isPresent();           // true  
  4. optional.get();                 // "bam"  
  5. optional.orElse("fallback");    // "bam"  
  6.    
  7. optional.ifPresent((s) -> System.out.println(s.charAt(0)));     // "b"  



Streams Top

java.util.Stream表示了某一種元素的序列,在這些元素上能夠進行各類操做。Stream操做能夠是中間操做,也能夠是完結操做。完結操做 會返回一個某種類型的值,而中間操做會返回流對象自己,而且你能夠經過屢次調用同一個流操做方法來將操做結果串起來(就像StringBuffer的 append方法同樣————譯者注)。Stream是在一個源的基礎上建立出來的,例如java.util.Collection中的list或者 set(map不能做爲Stream的源)。Stream操做每每能夠經過順序或者並行兩種方式來執行。

咱們先了解一下序列流。首先,咱們經過string類型的list的形式建立示例數據:

Java代碼
  1. List stringCollection = new ArrayList<>();  
  2. stringCollection.add("ddd2");  
  3. stringCollection.add("aaa2");  
  4. stringCollection.add("bbb1");  
  5. stringCollection.add("aaa1");  
  6. stringCollection.add("bbb3");  
  7. stringCollection.add("ccc");  
  8. stringCollection.add("bbb2");  
  9. stringCollection.add("ddd1");  

Java 8中的Collections類的功能已經有所加強,你能夠之直接經過調用Collections.stream()或者Collection.parallelStream()方法來建立一個流對象。下面的章節會解釋這個最經常使用的操做。

Filter

Filter接受一個predicate接口類型的變量,並將全部流對象中的元素進行過濾。該操做是一箇中間操做,所以它容許咱們在返回結果的基 礎上再進行其餘的流操做(forEach)。ForEach接受一個function接口類型的變量,用來執行對每個元素的操做。ForEach是一個 停止操做。它不返回流,因此咱們不能再調用其餘的流操做。

Java代碼
  1. stringCollection  
  2.     .stream()  
  3.     .filter((s) -> s.startsWith("a"))  
  4.     .forEach(System.out::println);  
  5.    
  6. // "aaa2", "aaa1"  

Sorted

Sorted是一箇中間操做,可以返回一個排過序的流對象的視圖。流對象中的元素會默認按照天然順序進行排序,除非你本身指定一個Comparator接口來改變排序規則。

Java代碼
  1. stringCollection  
  2.     .stream()  
  3.     .sorted()  
  4.     .filter((s) -> s.startsWith("a"))  
  5.     .forEach(System.out::println);  
  6.    
  7. // "aaa1", "aaa2"  

必定要記住,sorted只是建立一個流對象排序的視圖,而不會改變原來集合中元素的順序。原來string集合中的元素順序是沒有改變的。

Java代碼
  1. System.out.println(stringCollection);  
  2. // ddd2, aaa2, bbb1, aaa1, bbb3, ccc, bbb2, ddd1  

Map

map是一個對於流對象的中間操做,經過給定的方法,它可以把流對象中的每個元素對應到另一個對象上。下面的例子就演示瞭如何把每一個 string都轉換成大寫的string. 不但如此,你還能夠把每一種對象映射成爲其餘類型。對於帶泛型結果的流對象,具體的類型還要由傳遞給map的泛型方法來決定。

Java代碼
  1. stringCollection  
  2.     .stream()  
  3.     .map(String::toUpperCase)  
  4.     .sorted((a, b) -> b.compareTo(a))  
  5.     .forEach(System.out::println);  
  6.    
  7. // "DDD2", "DDD1", "CCC", "BBB3", "BBB2", "AAA2", "AAA1"  

Match

匹配操做有多種不一樣的類型,都是用來判斷某一種規則是否與流對象相互吻合的。全部的匹配操做都是終結操做,只返回一個boolean類型的結果。

Java代碼
  1. boolean anyStartsWithA =   
  2.     stringCollection  
  3.         .stream()  
  4.         .anyMatch((s) -> s.startsWith("a"));  
  5.    
  6. System.out.println(anyStartsWithA);      // true  
  7.    
  8. boolean allStartsWithA =   
  9.     stringCollection  
  10.         .stream()  
  11.         .allMatch((s) -> s.startsWith("a"));  
  12.    
  13. System.out.println(allStartsWithA);      // false  
  14.    
  15. boolean noneStartsWithZ =   
  16.     stringCollection  
  17.         .stream()  
  18.         .noneMatch((s) -> s.startsWith("z"));  
  19.    
  20. System.out.println(noneStartsWithZ);      // true  

Count

Count是一個終結操做,它的做用是返回一個數值,用來標識當前流對象中包含的元素數量。

Java代碼
  1. long startsWithB =   
  2.     stringCollection  
  3.         .stream()  
  4.         .filter((s) -> s.startsWith("b"))  
  5.         .count();  
  6.    
  7. System.out.println(startsWithB);    // 3  

Reduce

該操做是一個終結操做,它可以經過某一個方法,對元素進行削減操做。該操做的結果會放在一個Optional變量裏返回。

Java代碼
  1. Optional reduced =  
  2.     stringCollection  
  3.         .stream()  
  4.         .sorted()  
  5.         .reduce((s1, s2) -> s1 + "#" + s2);  
  6.    
  7. reduced.ifPresent(System.out::println);  
  8. // "aaa1#aaa2#bbb1#bbb2#bbb3#ccc#ddd1#ddd2"  



Parallel Streams Top

像上面所說的,流操做能夠是順序的,也能夠是並行的。順序操做經過單線程執行,而並行操做則經過多線程執行。

下面的例子就演示瞭如何使用並行流進行操做來提升運行效率,代碼很是簡單。

首先咱們建立一個大的list,裏面的元素都是惟一的:

Java代碼
  1. int max = 1000000;  
  2. List values = new ArrayList<>(max);  
  3. for (int i = 0; i < max; i++) {  
  4.     UUID uuid = UUID.randomUUID();  
  5.     values.add(uuid.toString());  
  6. }  

如今,咱們測量一下對這個集合進行排序所使用的時間。

順序排序

Java代碼
  1. long t0 = System.nanoTime();  
  2.    
  3. long count = values.stream().sorted().count();  
  4. System.out.println(count);  
  5.    
  6. long t1 = System.nanoTime();  
  7.    
  8. long millis = TimeUnit.NANOSECONDS.toMillis(t1 - t0);  
  9. System.out.println(String.format("sequential sort took: %d ms", millis));  
  10.    
  11. // sequential sort took: 899 ms  

並行排序

Java代碼
  1. long t0 = System.nanoTime();  
  2.    
  3. long count = values.parallelStream().sorted().count();  
  4. System.out.println(count);  
  5.    
  6. long t1 = System.nanoTime();  
  7.    
  8. long millis = TimeUnit.NANOSECONDS.toMillis(t1 - t0);  
  9. System.out.println(String.format("parallel sort took: %d ms", millis));  
  10.    
  11. // parallel sort took: 472 ms  

如你所見,全部的代碼段幾乎都相同,惟一的不一樣就是把stream()改爲了parallelStream(), 結果並行排序快了50%。


Map Top

正如前面已經提到的那樣,map是不支持流操做的。而更新後的map如今則支持多種實用的新方法,來完成常規的任務。

Java代碼
  1. Map map = new HashMap<>();  
  2.    
  3. for (int i = 0; i < 10; i++) {  
  4.     map.putIfAbsent(i, "val" + i);  
  5. }  
  6.    
  7. map.forEach((id, val) -> System.out.println(val));  

上面的代碼風格是徹底自解釋的:putIfAbsent避免咱們將null寫入;forEach接受一個消費者對象,從而將操做實施到每個map中的值上。

下面的這個例子展現瞭如何使用函數來計算map的編碼:

Java代碼
  1. map.computeIfPresent(3, (num, val) -> val + num);  
  2. map.get(3);             // val33  
  3.    
  4. map.computeIfPresent(9, (num, val) -> null);  
  5. map.containsKey(9);     // false  
  6.    
  7. map.computeIfAbsent(23, num -> "val" + num);  
  8. map.containsKey(23);    // true  
  9.    
  10. map.computeIfAbsent(3, num -> "bam");  
  11. map.get(3);             // val33  

接下來,咱們將學習,當給定一個key值時,如何把一個實例從對應的key中移除:

Java代碼
  1. map.remove(3, "val3");  
  2. map.get(3);             // val33  
  3.    
  4. map.remove(3, "val33");  
  5. map.get(3);             // null  

另外一個有用的方法:

Java代碼
  1. map.getOrDefault(42, "not found");  // not found  

將map中的實例合併也是很是容易的:

Java代碼
  1. map.merge(9, "val9", (value, newValue) -> value.concat(newValue));  
  2. map.get(9);             // val9  
  3.    
  4. map.merge(9, "concat", (value, newValue) -> value.concat(newValue));  
  5. map.get(9);             // val9concat  

合併操做先看map中是否沒有特定的key/value存在,若是是,則把key/value存入map,不然merging函數就會被調用,對現有的數值進行修改。


時間日期API Top

Java 8 包含了全新的時間日期API,這些功能都放在了java.time包下。新的時間日期API是基於Joda-Time庫開發的,可是也不盡相同。下面的例子就涵蓋了大多數新的API的重要部分。

Clock

Clock提供了對當前時間和日期的訪問功能。Clock是對當前時區敏感的,並可用於替代 System.currentTimeMillis()方法來獲取當前的毫秒時間。當前時間線上的時刻能夠用Instance類來表示。Instance 也可以用於建立原先的java.util.Date對象。

Java代碼
  1. Clock clock = Clock.systemDefaultZone();  
  2. long millis = clock.millis();  
  3.    
  4. Instant instant = clock.instant();  
  5. Date legacyDate = Date.from(instant);   // legacy java.util.Date  

Timezones

時區類能夠用一個ZoneId來表示。時區類的對象能夠經過靜態工廠方法方便地獲取。時區類還定義了一個偏移量,用來在當前時刻或某時間與目標時區時間之間進行轉換。

Java代碼
  1. System.out.println(ZoneId.getAvailableZoneIds());  
  2. // prints all available timezone ids  
  3.    
  4. ZoneId zone1 = ZoneId.of("Europe/Berlin");  
  5. ZoneId zone2 = ZoneId.of("Brazil/East");  
  6. System.out.println(zone1.getRules());  
  7. System.out.println(zone2.getRules());  
  8.    
  9. // ZoneRules[currentStandardOffset=+01:00]  
  10. // ZoneRules[currentStandardOffset=-03:00]  

LocalTime

本地時間類表示一個沒有指定時區的時間,例如,10 p.m.或者17:30:15,下面的例子會用上面的例子定義的時區建立兩個本地時間對象。而後咱們會比較兩個時間,並計算它們之間的小時和分鐘的不一樣。

Java代碼
  1. LocalTime now1 = LocalTime.now(zone1);  
  2. LocalTime now2 = LocalTime.now(zone2);  
  3.    
  4. System.out.println(now1.isBefore(now2));  // false  
  5.    
  6. long hoursBetween = ChronoUnit.HOURS.between(now1, now2);  
  7. long minutesBetween = ChronoUnit.MINUTES.between(now1, now2);  
  8.    
  9. System.out.println(hoursBetween);       // -3  
  10. System.out.println(minutesBetween);     // -239  

LocalTime是由多個工廠方法組成,其目的是爲了簡化對時間對象實例的建立和操做,包括對時間字符串進行解析的操做。

Java代碼
  1. LocalTime late = LocalTime.of(23, 59, 59);  
  2. System.out.println(late);       // 23:59:59  
  3.    
  4. DateTimeFormatter germanFormatter =  
  5.     DateTimeFormatter  
  6.         .ofLocalizedTime(FormatStyle.SHORT)  
  7.         .withLocale(Locale.GERMAN);  
  8.    
  9. LocalTime leetTime = LocalTime.parse("13:37", germanFormatter);  
  10. System.out.println(leetTime);   // 13:37  

LocalDate

本地時間表示了一個獨一無二的時間,例如:2014-03-11。這個時間是不可變的,與LocalTime是同源的。下面的例子演示瞭如何經過加減日,月,年等指標來計算新的日期。記住,每一次操做都會返回一個新的時間對象。

Java代碼
  1. LocalDate today = LocalDate.now();  
  2. LocalDate tomorrow = today.plus(1, ChronoUnit.DAYS);  
  3. LocalDate yesterday = tomorrow.minusDays(2);  
  4.    
  5. LocalDate independenceDay = LocalDate.of(2014, Month.JULY, 4);  
  6. DayOfWeek dayOfWeek = independenceDay.getDayOfWeek();  
  7. System.out.println(dayOfWeek);    // FRIDAYParsing a LocalDate from a string is just as simple as parsing a LocalTime:  

解析字符串並造成LocalDate對象,這個操做和解析LocalTime同樣簡單。

Java代碼
  1. DateTimeFormatter germanFormatter =  
  2.     DateTimeFormatter  
  3.         .ofLocalizedDate(FormatStyle.MEDIUM)  
  4.         .withLocale(Locale.GERMAN);  
  5.    
  6. LocalDate xmas = LocalDate.parse("24.12.2014", germanFormatter);  
  7. System.out.println(xmas);   // 2014-12-24  

LocalDateTime

LocalDateTime表示的是日期-時間。它將剛纔介紹的日期對象和時間對象結合起來,造成了一個對象實例。LocalDateTime是不可變的,與LocalTime和LocalDate的工做原理相同。咱們能夠經過調用方法來獲取日期時間對象中特定的數據域。

Java代碼
  1. LocalDateTime sylvester = LocalDateTime.of(2014, Month.DECEMBER, 31, 23, 59, 59);  
  2.    
  3. DayOfWeek dayOfWeek = sylvester.getDayOfWeek();  
  4. System.out.println(dayOfWeek);      // WEDNESDAY  
  5.    
  6. Month month = sylvester.getMonth();  
  7. System.out.println(month);          // DECEMBER  
  8.    
  9. long minuteOfDay = sylvester.getLong(ChronoField.MINUTE_OF_DAY);  
  10. System.out.println(minuteOfDay);    // 1439  

若是再加上的時區信息,LocalDateTime可以被轉換成Instance實例。Instance可以被轉換成之前的java.util.Date對象。

Java代碼
  1. Instant instant = sylvester  
  2.         .atZone(ZoneId.systemDefault())  
  3.         .toInstant();  
  4.    
  5. Date legacyDate = Date.from(instant);  
  6. System.out.println(legacyDate);     // Wed Dec 31 23:59:59 CET 2014  

格式化日期-時間對象就和格式化日期對象或者時間對象同樣。除了使用預約義的格式之外,咱們還能夠建立自定義的格式化對象,而後匹配咱們自定義的格式。

Java代碼
  1. DateTimeFormatter formatter =  
  2.     DateTimeFormatter  
  3.         .ofPattern("MMM dd, yyyy - HH:mm");  
  4.    
  5. LocalDateTime parsed = LocalDateTime.parse("Nov 03, 2014 - 07:13", formatter);  
  6. String string = formatter.format(parsed);  
  7. System.out.println(string);     // Nov 03, 2014 - 07:13  

不一樣於java.text.NumberFormat,新的DateTimeFormatter類是不可變的,也是線程安全的。

更多的細節,請看 這裏


Annotations Top

Java 8中的註解是可重複的。讓咱們直接深刻看看例子,弄明白它是什麼意思。

首先,咱們定義一個包裝註解,它包括了一個實際註解的數組

Java代碼
  1. @interface Hints {  
  2.     Hint[] value();  
  3. }  
  4.    
  5. @Repeatable(Hints.class)  
  6. @interface Hint {  
  7.     String value();  
  8. }  

只要在前面加上註解名:@Repeatable,Java 8 容許咱們對同一類型使用多重註解:

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

Java代碼
  1. @Hints({@Hint("hint1"), @Hint("hint2")})  
  2. class Person {}  

變體2:使用可重複註解(新方法):

Java代碼
  1. @Hint("hint1")  
  2. @Hint("hint2")  
  3. class Person {}  

使用變體2,Java編譯器可以在內部自動對@Hint進行設置。這對於經過反射來讀取註解信息來講,是很是重要的。

Java代碼
  1. Hint hint = Person.class.getAnnotation(Hint.class);  
  2. System.out.println(hint);                   // null  
  3.    
  4. Hints hints1 = Person.class.getAnnotation(Hints.class);  
  5. System.out.println(hints1.value().length);  // 2  
  6.    
  7. Hint[] hints2 = Person.class.getAnnotationsByType(Hint.class);  
  8. System.out.println(hints2.length);          // 2  

儘管咱們絕對不會在Person類上聲明@Hints註解,可是它的信息仍然能夠經過getAnnotation(Hints.class)來讀 取。而且,getAnnotationsByType方法會更方便,由於它賦予了全部@Hints註解標註的方法直接的訪問權限。

Java代碼
  1. @Target({ElementType.TYPE_PARAMETER, ElementType.TYPE_USE})  
  2. @interface MyAnnotation {}  



總結 Top

Java 8編程指南就到此告一段落。固然,還有不少內容須要進一步研究和說明。這就須要靠讀者您來對JDK 8進行探究了,例如:Arrays.parallelSort, StampedLock和CompletableFuture等等 ———— 我這裏只是舉幾個例子而已。

我但願這個博文可以對您有所幫助,也但願您閱讀愉快。完整的教程源代碼放在了 GitHub上。您能夠盡情地 fork,並請經過 Twitter告訴我您的反饋。

原文連接:  winterbe 翻譯: ImportNew.com - 黃小非
譯文連接: http://www.importnew.com/10360.html
-------------------------------------------------------------------------------------------------------------------
jav1.9新特性
 
加快OpenJDK的開發速度:繼2014年3月份發佈了Java 8以後,咱們進入下一個兩年的發佈週期。 Java 9預計在2016年發佈,而且已經公佈了JEP(JDK改進提議)中的前期列表。同時,咱們已經把一些新特性整理到了JSR(Java規範請求),還有提 出了一些但願包括在新版本中的其餘特性。

 

這些重要的特性都包括在Jigsaw項目中。顯著的性能改善和期待已久的API包括:進程API更新,JSON將成爲java.util的一部分,貨幣處理API對於想處在技術最前沿的你,可從這裏得到Java 9的初期版本。

 

被接受的特性

1. Jigsaw 項目;模塊化源碼

Jigsaw項目是爲了模塊化Java代碼、將JRE分紅可相互協做的組件,這也是Java 9 衆多特點種的一個。JEP是邁向Jigsaw四步中的第一步,它不會改變JRE和JDK的真實結構。JEP是爲了模塊化JDK源代碼,讓編譯系統可以模塊 編譯並在構建時檢查模塊邊界。這個項目本來是隨Java 8發佈的,但因爲推遲,因此將把它加到Java 9.

 

一旦它完成,它可能容許根據一個項目需求自定義組件從而減小rt.jar的大小。在JDK 7 和JDK 8的rt.jar包中有大約20,000個類,但有不少類在一些特定的環境裏面並無被用到(即便在Java 8的緊湊分佈特性中已經包含了一部分解決方法也存在着類冗餘)。這麼作是爲了能讓Java可以容易應用到小型計算設備(好比網絡設備)中,提升它的安全和 性能,同時也能讓開發者更容易構建和維護這些類庫。

 

2. 簡化進程API 

截止到目前,Java控制與管理系統進程的能力是有限的。舉個例子,如今爲了簡便獲取你程序的進程PID,你要麼調用本地程序要麼要本身使用一些變通方案。更多的是,每一個(系統)平臺須要有一個不一樣實現來確保你能得到正確的結果。 

指望代碼能獲取Linux PIDS,如今是以下方式: 



 

在Java 9中,能夠變換成以下方式(支持全部的操做系統): 



 

此次更新將會擴展Java與操做系統的交互能力:新增一些新的直接明瞭的方法去處理PIDs,進程名字和狀態以及枚舉多個JVM和進程以及更多事情。 

 

3. 輕量級 JSON API 

目前有多種處理JSON的Java工具,但JSON API 獨到之處在於JSON API將做爲Java語言的一部分,輕量而且運用Java 8的新特性。它將放在java.util包裏一塊兒發佈(但在JSR 353裏面的JSON是用第三方包或者其餘的方法處理的). 

 

4. 錢和貨幣的API 

在Java 8引進了日期和時間的API以後, Java 9引入了新的貨幣API, 用以表示貨幣, 支持幣種之間的轉換和各類複雜運算. 關於這個項目的具體狀況, 請訪問https://github.com/JavaMoney,裏面已經給出了使用說明和示例, 如下是幾個重要的例子: 



 

更多關於 JSR 354的內容 

 

5. 改善鎖爭用機制

鎖爭用是限制許多Java多線程應用性能的瓶頸. 新的機制在改善Java對象監視器的性能方面已經獲得了多種基準(benchmark)的驗證, 其中包括Volano. 測試中通信服務器開放了海量的進程來鏈接客戶端, 其中有不少鏈接都申請同一個資源, 以此模擬重負荷平常應用.

 

經過諸如此類的壓力測試咱們能夠估算JVM的極限吞吐量(每秒的消息數量). JEP在22種不一樣的測試中都獲得了出色的成績, 新的機制若是能在Java 9中獲得應用的話, 應用程序的性能將會大大提高.

關於JEP 143的更多內容 

 

6. 代碼分段緩存

Java 9的另外一個性能提高來自於JIT(Just-in-time)編譯器. 當某段代碼被大量重複執行的時候, 虛擬機會把這段代碼編譯成機器碼(native code)並儲存在代碼緩存裏面, 進而經過訪問緩存中不一樣分段的代碼來提高編譯器的效率.

 

和原來的單一緩存區域不一樣的是, 新的代碼緩存根據代碼自身的生命週期而分爲三種:

  • 永駐代碼(JVM 內置 / 非方法代碼)
  • 短時間代碼(僅在某些條件下適用的配置性(profiled)代碼)
  • 長期代碼(非配置性代碼)

緩存分段會在各個方面提高程序的性能, 好比作垃圾回收掃描的時候能夠直接跳過非方法代碼(永駐代碼), 從而提高效率.

更多關於JEP 197的內容 

 

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

智能Java編譯工具sjavac的第一階段開始於JEP 139這個項目, 用於在多核處理器上提高JDK的編譯速度. 如今這個項目已經進入第二階段(JEP 199), 目的是改進sjavac並讓其成爲取代目前JDK編譯工具javac的Java默認的通用編譯工具.

 

其餘值得期待的內容:

8. HTTP 2.0客戶端

HTTP 2.0標準雖然還沒正式發佈, 可是已經進入了最終審查階段, 預計能夠在Java 9發佈以前審查完畢. JEP 110將會從新定義並實現一個全新的Java HTTP客戶端, 用來取代如今的HttpURLConnection, 同時也會實現HTTP 2.0和網絡接口(原文websockets). 它如今還沒被JEP正式承認但咱們但願在Java 9中包含這一項目的內容.

官方的HTTP 2.0 RFC(Request for Comments, 官方技術討論/會議記錄等等的一系列文檔記錄)預訂於2015年2月發佈, 它是基於Google發佈的SPDY(Speedy, 快速的)協議. 基於SPDY協議的網絡相對於基於HTTP 1.1協議的網絡有11.81%到47.7%之間的顯著提速, 如今已經有瀏覽器實現了這個協議.

 

9. Kulla計劃: Java的REPL實現

這個取名爲Kulla的項目最近宣佈將於2015年4月整合測試, 雖然已經不太有但願能遇上Java 9的發佈, 但若是進度快的話或許恰好能遇上. 如今Java並無來自官方的REPL(Read-Eval-Print-Loop)方式, 也就是說如今若是你想要跑幾行Java代碼作一個快速的測試, 你仍然須要把這幾行代碼封裝在項目或者方法裏面. 雖然在一些流行的IDE裏面有Java REPL工具, 但它們並無官方支持, 而Kulla項目或許就能成爲Java官方發佈的REPL解決方案. 

更多關於Kulla計劃的內容 

 

這些新功能出自何處?

 

JEP和JSR並非無中生有,下面就介紹一下Java發展的生態環境:

小組 - 對特定技術內容, 好比安全、網絡、Swing、HotSpot、有共同興趣的組織和我的。

 

項目 - 編寫代碼, 文檔以及其餘工做,至少由一個小組贊助和支持,好比最近的Lambda計劃,Jigsaw計劃和Sumatra計劃。

 

JDK改進提案(JEP) - 每當須要有新的嘗試的時候, JEP能夠在JCP(Java Community Process)以前或者同時提出非正式的規範(specification),被正是承認的JEP正式寫進JDK的發展路線圖並分配版本號。

 

Java規範提案(JSR) - 新特性的規範出如今這一個階段,能夠來自於小組 / 項目、JEP、 JCP成員或者Java社區(community)成員的提案,每一個Java版本都由相應的JSR支持, Java 9暫時尚未。

該博文轉自:http://huyumin.iteye.com/blog/2154441

相關文章
相關標籤/搜索