日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

JDK6 新特性

發布時間:2024/8/1 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 JDK6 新特性 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

JDK6新特性目錄導航:

  • Desktop類和SystemTray類
  • JAXB2實現對象與XML之間的映射
  • StAX
  • Compiler API
  • 輕量級 Http Server API
  • 插入式注解處理API(Pluggable Annotation Processing API)
  • 用Console開發控制臺程序
  • 對腳本語言的支持(如:ruby,groovy,javascript)
  • Common Annotations

?

Desktop類和SystemTray類

JDK6在java.awt包下新增了兩個類:Desktop和SystemTray

Desktop類:允許 Java 應用程序啟動已在本機桌面上注冊的關聯應用程序來處理 URI 或文件。

Desktop類的主要方法

1.browse(URI uri): 使用默認瀏覽器打開uri資源。

2.checkActionSupport(Action actionType): 檢查是否支持的Action。

3.open(File file): 啟動關聯應用程序來打開文件。

4.edit(File file): 啟動關聯編輯器應用程序并打開一個文件編輯。

5.print(File file): 使用關聯應用程序打印文件。

6.mail():?啟動用戶默認郵件客戶端的郵件組合窗口。

7.mail(URI mailtoURI):?啟動用戶默認郵件客戶端的郵件組合窗口, 填充由 mailto:URI 指定的消息字段。

示例代碼:

1 import java.awt.*; 2 import java.io.File; 3 import java.io.IOException; 4 import java.net.URI; 5 6 public class Test { 7 public static void main(String[] args) throws IOException { 8 //先判斷當前平臺是否支持Desktop類 9 if (Desktop.isDesktopSupported()) { 10 //獲取Desktop實例 11 Desktop desktop = Desktop.getDesktop(); 12 //使用默認瀏覽器打開鏈接 13 desktop.browse(URI.create("http://www.cnblogs.com/peter1018")); 14 // 打開指定文件/文件夾 15 desktop.open(new File("D:\\")); 16 17 //...... 18 19 //其他方法可以自行演示... 20 }else { 21 System.out.println("當前平臺不支持 Desktop類!"); 22 } 23 24 } 25 26 }

SystemTray類:代表一個系統托盤桌面。在微軟的Windows上,它被稱為“任務欄”狀態區域,在Gnome上,它被稱為“通知”在KDE上,它被稱為“系統托盤”。該系統托盤由在桌面上運行的所有應用程序共享。

SystemTray類的主要方法:

1.isSupported() : 檢測系統是否支持SystemTray類。

2.getSystemTray() : 獲得SystemTray實例。

1.add(TrayIcon trayIcon):?在“系統托盤”上添加一個“TrayIcon”。TrayIcon對象代表一個托盤圖標,它可以有一個工具提示(文本),一個圖像,一個彈出框菜單,以及一組與之相關的偵聽器。托盤圖標一旦出現,就會在系統托盤中顯示。

2.remove(TrayIcon trayIcon): 刪除指定的“TrayIcon”。

3.getTrayIcons():?返回一個由這個托盤添加到托盤上的所有圖標的數組應用程序。

4.getTrayIconSize():??以像素為單位,返回在系統托盤中占據的一個托盤圖標的大小。

5.addPropertyChangeListener(String propertyName,PropertyChangeListener listener): 將?PropertyChangeListener 添加到監聽器

6.removePropertyChangeListener(String propertyName,PropertyChangeListener listener): 將PropertyChangeListener 從監聽器移除

7.getPropertyChangeListeners(String propertyName) : 返回所有已關聯的監聽器數組

示例代碼:

?

1 import javax.swing.*; 2 import java.awt.*; 3 4 public class Test { 5 public static void main(String[] args) throws AWTException { 6 //先判斷當前平臺是否支持SystemTray類 7 if (SystemTray.isSupported()) { 8 //獲取SystemTray實例 9 SystemTray systemTray = SystemTray.getSystemTray(); 10 //獲得托盤顯示圖標 11 ImageIcon imageIcon=new ImageIcon("D:\\icon.jpg"); 12 //獲得Image對象 13 Image icon=imageIcon.getImage(); 14 //任務欄程序托盤圖標 15 TrayIcon trayicon = new TrayIcon(icon,"JAVA系統托盤"); 16 //關鍵點,設置托盤圖標的自適應屬性,這樣才能在系統顯示托盤處正常顯示出需要的圖片。 17 trayicon.setImageAutoSize(true); 18 //添加系統托盤 19 systemTray.add(trayicon); 20 //...... 21 //其他方法可以自行演示... 22 //移除系統托盤 23 systemTray.remove(trayicon); 24 }else { 25 System.out.println("當前平臺不支持 SystemTray類!"); 26 } 27 28 } 29 30 }

?

展示結果如下:

?

JAXB2實現對象與XML之間的映射

JAXB是Java?Architecture?for?XML?Binding的縮寫,可以將一個Java對象轉變成為XML格式,反之亦然。我們把對象與關系數據庫之間的映射稱為ORM,?其實也可以把對象與XML之間的映射稱為OXM(Object?XML?Mapping)。原來JAXB是Java?EE的一部分,在JDK6中,SUN將其放到了Java?SE中,這也是SUN的一貫做法。JDK6中自帶的這個JAXB版本是2.0,?比起1.0(JSR?31)來,JAXB2(JSR?222)用JDK5的新特性Annotation來標識要作綁定的類和屬性等,這就極大簡化了開發的工作量。實際上,在Java?EE?5.0中,EJB和Web?Services也通過Annotation來簡化開發工作。另外,JAXB2在底層是用StAX(JSR?173)來處理XML文檔。?

重要的注解和說明

注解說明

@XmlRootElement

將類或enum類型映射到XML元素,類名或名作為根節點

@XmlAttribute

將JavaBean屬性映射到XML屬性

@XmlElement

將JavaBean屬性映射到源自屬性名的XML元素

@XmlAnyAttribute

將JavaBean屬性映射到通配符屬性的映射

@XmlAnyElement

將JavaBean屬性映射到XML infoset或JAXB

@XmlElements

一個用于多XmlElement注解的容器。

@XmlID

將JavaBean屬性映射到XML ID

@XmlIDREF

將JavaBean屬性映射到XML IDREF

@XmlList

用來將一個屬性映射到一個List

@XmlSchema

將包映射到XML名稱空間

@XmlTransient

該屬性無需映射到XML

?

示例代碼:

Address類

1 import javax.xml.bind.annotation.XmlAttribute; 2 import javax.xml.bind.annotation.XmlElement; 3 4 public class Address { 5 6 @XmlAttribute 7 String province; 8 @XmlElement 9 String area; 10 @XmlElement 11 String street; 12 13 public Address() {} 14 15 public Address(String province, String area, String street) { 16 this.province = province; 17 this.area = area; 18 this.street = street; 19 } 20 21 @Override 22 public String toString() { 23 return "Address{" + 24 "province='" + province + '\'' + 25 ", area='" + area + '\'' + 26 ", street='" + street + '\'' + 27 '}'; 28 } 29 }

Person類

1 import javax.xml.bind.annotation.XmlAttribute; 2 import javax.xml.bind.annotation.XmlElement; 3 import javax.xml.bind.annotation.XmlRootElement; 4 5 @XmlRootElement 6 public class Person{ 7 8 @XmlAttribute 9 private String name; 10 11 @XmlElement 12 private int age; 13 14 @XmlElement 15 private Address address; 16 17 public Person() { 18 } 19 20 public Person(String name, int age, Address address) { 21 this.name = name; 22 this.age = age; 23 this.address = address; 24 } 25 26 @Override 27 public String toString() { 28 return "Person{" + 29 "name='" + name + '\'' + 30 ", age=" + age + 31 ", address=" + address + 32 '}'; 33 } 34 }

測試類:

1 import javax.xml.bind.JAXBContext; 2 import javax.xml.bind.JAXBException; 3 import javax.xml.bind.Marshaller; 4 import javax.xml.bind.Unmarshaller; 5 import java.io.FileReader; 6 import java.io.FileWriter; 7 import java.io.IOException; 8 9 public class Test { 10 public static void main(String[] args) throws JAXBException, IOException { 11 JAXBContext jaxbContext = JAXBContext.newInstance(Person.class); 12 13 //根據Person對象轉換為person.xml文件 14 Marshaller marshaller = jaxbContext.createMarshaller(); 15 Address address = new Address("廣東省","深圳市","寶安區"); 16 Person person = new Person("niannianjiuwang", 20, address); 17 FileWriter fileWriter = new FileWriter("D:\\person.xml"); 18 marshaller.marshal(person, fileWriter); 19 20 //根據person.xml文件轉換為對象 21 FileReader fileReader = new FileReader("D:\\person.xml"); 22 Unmarshaller unmarshaller = jaxbContext.createUnmarshaller(); 23 Person personNew = (Person) unmarshaller.unmarshal(fileReader); 24 System.out.println(personNew); 25 } 26 }

輸出結果:

先看看person.xml文件:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <person name="niannianjiuwang"><age>20</age><address province="廣東省"><area>深圳市</area><street>寶安區</street></address> </person>

控制臺結果:

Person{name='niannianjiuwang', age=20, address=Address{province='廣東省', area='深圳市', street='寶安區'}}

?

StAX

StAX的來歷 :

在JAXP1.3(JSR 206)有兩種處理XML文檔的方法:DOM(Document Object Model)和SAX(Simple API for XML).由于JDK6.0中的JAXB2(JSR 222)和JAX-WS 2.0(JSR 224)都會用到StAX所以Sun決定把StAX加入到JAXP家族當中來,并將JAXP的版本升級到1.4(JAXP1.4是JAXP1.3的維護版本). JDK6里面JAXP的版本就是1.4。

StAX簡介:

StAX是Streaming API for XML的縮寫,它包含在2004年3月的JSR 173 中。StAX是JDK6.0中包含的新特性。
在推式模型中,直到整個XML文件全部被解析,解析器才會產生解析事件。而拉式解析由應用程序來控制,也就是說解析事件由應用程序產生。這就意味著,你可以暫緩解析、解析時跳過某個元素或者同時解析多個文件。用DOM解析式要先將XML文件解析成DOM結構,因此降低了解析效率。使用StAX,解析事件在XML文件解析過程中產生。

下面是各種解析方法之間的比較:

XML Parser API Feature Summary
FeatureStAXSAXDOMTrAX
API TypePull, streamingPull, streamingIn memory treeXSLT Rule
Ease of UseHighMediumHighMedium
XPath CapabilityNoNoYesYes
CPU and Memory EfficiencyGoodGoodVariesVaries
Forward OnlyYesYesNoNo
Read XMLYesYesYesYes
Write XMLYesNoYesYes
Create, Read, Update, DeleteNoNoYesNo

StAX API同樣也在JWSDP(Java Web Services Developer Pack )1.6中得到實現,你可以在包javax.xml.stream 中找到它。XMLStreamReader接口用來解析XML文件。XMLStreamWriter接口用來生成XML文件,XMLEventReader用一個對象事件迭代器來解析XML事件。與之相反,XMLStreamReader采用的是游標機制。

示例代碼:

?

1 import javax.xml.stream.*; 2 import javax.xml.stream.events.XMLEvent; 3 import java.io.FileInputStream; 4 import java.io.FileNotFoundException; 5 import java.io.FileOutputStream; 6 7 public class Test { 8 public static void main(String[] args) throws FileNotFoundException, XMLStreamException { 9 writeXMLByStAX();//用XMLStreamWriter寫xml文檔 10 readXMLByStAX();//用XMLEventReader解析xml文檔 11 } 12 13 /** 14 * 通過StAX讀XML 15 */ 16 private static void readXMLByStAX() throws XMLStreamException, FileNotFoundException { 17 XMLInputFactory xmlif = XMLInputFactory.newInstance(); 18 XMLEventReader xmler = xmlif.createXMLEventReader(new FileInputStream("D:\\write.xml")); 19 XMLEvent event; 20 StringBuffer parsingResult = new StringBuffer(); 21 while (xmler.hasNext()) { 22 event = xmler.nextEvent(); 23 parsingResult.append(event.toString()); 24 } 25 System.out.println(parsingResult); 26 } 27 28 /** 29 * 通過StAX寫XML 30 */ 31 private static void writeXMLByStAX() throws FileNotFoundException, XMLStreamException { 32 XMLOutputFactory xmlOutputFactory = XMLOutputFactory.newFactory(); 33 XMLStreamWriter xmlStreamWriter = xmlOutputFactory.createXMLStreamWriter(new FileOutputStream("D:\\write.xml")); 34 35 // 寫入默認的 XML 聲明到xml文檔 36 xmlStreamWriter.writeStartDocument(); 37 // 寫入注釋到xml文檔 38 xmlStreamWriter.writeComment("testing comment"); 39 // 寫入一個catalogs根元素 40 xmlStreamWriter.writeStartElement("catalogs"); 41 xmlStreamWriter.writeNamespace("myUrl", "http://www.cnblogs.com/peter1018"); 42 xmlStreamWriter.writeAttribute("name","niannianjiuwang"); 43 // 寫入子元素catalog 44 xmlStreamWriter.writeStartElement("http://www.cnblogs.com/peter1018", "catalog"); 45 xmlStreamWriter.writeAttribute("id","StAX"); 46 xmlStreamWriter.writeCharacters("Apparel"); 47 // 寫入catalog元素的結束標簽 48 xmlStreamWriter.writeEndElement(); 49 // 寫入catalogs元素的結束標簽 50 xmlStreamWriter.writeEndElement(); 51 // 結束 XML 文檔 52 xmlStreamWriter.writeEndDocument(); 53 xmlStreamWriter.close(); 54 } 55 }

輸出結果:

write.xml文件內容:

<?xml version="1.0" ?><!--testing comment--><catalogs xmlns:myUrl="http://www.cnblogs.com/peter1018" name="niannianjiuwang"><myUrl:catalog id="StAX">Apparel</myUrl:catalog></catalogs>

?

控制臺打印結果:

<?xml version="1.0" encoding='UTF-8' standalone='no'?><!--testing comment--><catalogs name='niannianjiuwang' xmlns:myUrl='http://www.cnblogs.com/peter1018'><['http://www.cnblogs.com/peter1018']:myUrl:catalog id='StAX'>Apparel</['http://www.cnblogs.com/peter1018']:myUrl:catalog></catalogs>ENDDOCUMENT

?

Compiler API

Java編程語言編譯器javac讀取以Java編程語言編寫的源文件,并將它們編譯為字節碼class文件。或者,編譯器也可以使用注解找到源文件和類文件并使用comiler API。編譯器是一個命令行工具,但也可以使用Java compiler API調用。原話:官網介紹

我們可以用JDK6?的Compiler?API(JSR?199)去動態編譯Java源文件,Compiler?API結合反射功能就可以實現動態的產生Java代碼并編譯執行這些代碼,有點動態語言的特征。這個特性對于某些需要用到動態編譯的應用程序相當有用,?比如JSP?Web?Server,當我們手動修改JSP后,是不希望需要重啟Web?Server才可以看到效果的,這時候我們就可以用Compiler?API來實現動態編譯JSP文件,當然,現在的JSP?Web?Server也是支持JSP熱部署的,現在的JSP?Web?Server通過在運行期間通過Runtime.exec或ProcessBuilder來調用javac來編譯代碼,這種方式需要我們產生另一個進程去做編譯工作,不夠優雅而且容易使代碼依賴與特定的操作系統;Compiler?API通過一套易用的標準的API提供了更加豐富的方式去做動態編譯,而且是跨平臺的。

API Specification

  • javax.annotation.processing?- Annotation processing.
  • javax.lang.model?- Language model used in annotation processing and Compiler Tree API
    • javax.lang.model.element?- Language elements.
    • javax.lang.model.type?- Types.
    • javax.lang.model.util?- Language model utilities.
  • javax.tools?- Java Compiler API.
  • com.sun.source.*?- Compiler Tree API.

?

示例代碼:(Tips:運行代碼之前必須在D目錄下存放TestObject.java文件)

1 import javax.tools.JavaCompiler; 2 import javax.tools.JavaFileObject; 3 import javax.tools.StandardJavaFileManager; 4 import javax.tools.ToolProvider; 5 import java.io.IOException; 6 7 public class Test { 8 public static void main(String[] args) throws IOException { 9 JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); 10 StandardJavaFileManager standardJavaFileManager = compiler.getStandardFileManager(null,null,null); 11 Iterable<? extends JavaFileObject> sourcefiles = standardJavaFileManager.getJavaFileObjects("D:\\TestObject.java"); 12 compiler.getTask(null, standardJavaFileManager, null, null, null, sourcefiles).call(); 13 standardJavaFileManager.close(); 14 15 } 16 }

輸出結果:會在D目錄下生成TestObject.class文件。

輕量級 Http Server API?

JDK6 提供了一個簡單的Http Server API,據此我們可以構建自己的嵌入式Http Server,它支持Http和Https協議,提供了HTTP1.1的部分實現,沒有被實現的那部分可以通過擴展已有的Http Server API來實現,必須自己實現HttpHandler接口,HttpServer會調用HttpHandler實現類的回調方法來處理客戶端請求,我們把一個Http請求和它的響應稱為一個交換,包裝成HttpExchange類,HttpServer負責將HttpExchange傳給 HttpHandler實現類的回調方法。

示例代碼:

1 import com.sun.net.httpserver.HttpExchange; 2 import com.sun.net.httpserver.HttpHandler; 3 4 import java.io.*; 5 6 public class TestHandler implements HttpHandler { 7 8 9 @Override 10 public void handle(HttpExchange httpExchange) throws IOException { 11 System.out.println("==進入Hadnler方法"); 12 String responseMsg = "OK"; //響應信息 13 InputStream in = httpExchange.getRequestBody(); //獲得輸入流 14 BufferedReader reader = new BufferedReader(new InputStreamReader(in)); 15 String temp = null; 16 while((temp = reader.readLine()) != null) { 17 System.out.println("client request:"+temp); 18 } 19 httpExchange.sendResponseHeaders(200, responseMsg.length()); //設置響應頭屬性及響應信息的長度 20 OutputStream out = httpExchange.getResponseBody(); //獲得輸出流 21 out.write(responseMsg.getBytes()); 22 out.flush(); 23 httpExchange.close(); 24 } 25 } 1 import com.sun.net.httpserver.HttpServer; 2 import com.sun.net.httpserver.spi.HttpServerProvider; 3 4 import java.io.IOException; 5 import java.net.InetSocketAddress; 6 7 public class Test { 8 public static void main(String[] args) throws IOException { 9 //啟動服務,監聽來自客戶端的請求 10 HttpServerProvider provider = HttpServerProvider.provider(); 11 //監聽8888端口,能同時接受100個請求 12 HttpServer httpserver =provider.createHttpServer(new InetSocketAddress(8888), 100); 13 //將 /test 請求交給 TestHandler 處理器處理 14 httpserver.createContext("/test", new TestHandler()); 15 httpserver.setExecutor(null); 16 httpserver.start(); 17 System.out.println("server started"); 18 } 19 }

輸出結果:

server started ==進入Hadnler方法 ==進入Hadnler方法 ==進入Hadnler方法

?

插入式注解處理 API(Pluggable Annotation Processing API)

插入式注解處理API(JSR 269)提供一套標準API來處理Annotations(JSR 175)。實際上JSR 269不僅僅用來處理Annotation,它還建立了Java 語言本身的一個模型,它把method, package, constructor, type, variable, enum,,annotation等Java語言元素映射為Types和Elements, 從而將Java語言的語義映射成為對象,我們可以在javax.lang.model包下面可以看到這些類. 所以我們可以利用JSR 269提供的API來構建一個功能豐富的元編程(metaprogramming)環境。JSR 269用Annotation Processor在編譯期間而不是運行期間處理Annotation, Annotation Processor相當于編譯器的一個插件,所以稱為插入式注解處理。如果Annotation Processor處理Annotation時(執行process方法)產生了新的Java代碼,編譯器會再調用一次Annotation Processor,如果第二次處理還有新代碼產生,就會接著調用Annotation Processor,直到沒有新代碼產生為止。每執行一次process()方法被稱為一個"round",這樣整個Annotation processing過程可以看作是一個round的序列,JSR 269主要被設計成為針對Tools或者容器的API。

舉個例子,我們想建立一套基于Annotation的單元測試框架(如TestNG),在測試類里面用Annotation來標識測試期間需要執行的測試方法,如下所示:

@TestMethodpublic void testCheckName(){//do something here}

這時我們就可以用JSR 269提供的API來處理測試類,根據Annotation提取出需要執行的測試方法。

另一個例子是如果我們出于某種原因需要自行開發一個符合Java EE 5.0的Application Server(當然不建議這樣做),我們就必須處理Common Annotations(JSR 250),Web Services Metadata(JSR 181)等規范的Annotations,這時可以用JSR 269提供的API來處理這些Annotations. 在現在的開發工具里面,Eclipse 3.3承諾將支持JSR 269

下面我用代碼演示如何來用JSR 269提供的API來處理Annotations和讀取Java源文件的元數據(metadata)

@SupportedAnnotationTypes("PluggableAPT.ToBeTested")//可以用"*"表示支持所有Annotations @SupportedSourceVersion(SourceVersion.RELEASE_6) public class MyAnnotationProcessor extends AbstractProcessor {private void note(String msg) {processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE, msg);}public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {//annotations的值是通過@SupportedAnnotationTypes聲明的且目標源代碼擁有的所有Annotationsfor(TypeElement te:annotations){note("annotation:"+te.toString());}Set<? extends Element> elements = roundEnv.getRootElements();//獲取源代碼的映射對象for(Element e:elements){//獲取源代碼對象的成員List<? extends Element> enclosedElems = e.getEnclosedElements();//留下方法成員,過濾掉其他成員List<? extends ExecutableElement> ees = ElementFilter.methodsIn(enclosedElems);for(ExecutableElement ee:ees){note("--ExecutableElement name is "+ee.getSimpleName());List<? extends AnnotationMirror> as = ee.getAnnotationMirrors();//獲取方法的Annotationsnote("--as="+as); for(AnnotationMirror am:as){//獲取Annotation的值Map<? extends ExecutableElement, ? extends AnnotationValue> map= am.getElementValues();Set<? extends ExecutableElement> ks = map.keySet();for(ExecutableElement k:ks){//打印Annotation的每個值AnnotationValue av = map.get(k);note("----"+ee.getSimpleName()+"."+k.getSimpleName()+"="+av.getValue());}}}}return false;} } @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) @interface ToBeTested{String owner() default "Chinajash";String group(); }

編譯以上代碼,然后再創建下面的Testing對象,不要編譯Testing對象,我在后面會編譯它

public class Testing{ @ToBeTested(group="A")public void m1(){}@ToBeTested(group="B",owner="QQ")public void m2(){} @PostConstruct//Common Annotation里面的一個Annotationpublic void m3(){} }

下面我用以下命令編譯Testing對象

javac -XprintRounds -processor PluggableAPT.MyAnnotationProcessor Testing.java

-XprintRounds表示打印round的次數,運行上面命令后在控制臺會看到如下輸出:

Round 1:input files: {PluggableAPT.Testing}annotations: [PluggableAPT.ToBeTested, javax.annotation.PostConstruct]last round: false Note: annotation:PluggableAPT.ToBeTested Note: --ExecutableElement name is m1 Note: ") Note: ----m1.group=A Note: --ExecutableElement name is m2 Note: ", owner="QQ") Note: ----m2.group=B Note: ----m2.owner=QQ Note: --ExecutableElement name is m3 Note: --as=@javax.annotation.PostConstruct Round 2:input files: {}annotations: []last round: true

本來想用JDK6.0的Compiler API來執行上面編譯命令,可是好像現在Compiler API還不支持-processor參數,運行時總報以下錯誤

Exception in thread "main" java.lang.IllegalArgumentException: invalid flag: -processor PluggableAPT.MyAnnotationProcessor

調用Compiler API的代碼是這樣的

JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null); Iterable<? extends JavaFileObject> sourcefiles = fileManager.getJavaFileObjects("Testing.java"); Set<String> options = new HashSet<String>(); options.add("-processor PluggableAPT.MyAnnotationProcessor"); compiler.getTask(null, fileManager, null, options, null, sourcefiles).call();

不知道這是不是Compiler API的一個bug。

?

用Console開發控制臺程序

JDK6中提供 了java.io.Console類專用來訪問基于字符的控制臺設備。程序如果要與Windows下的cmd或者Linux下的Terminal交互,就可以用Console類代勞。但我們不總是能得到可用的Console,一個JVM是否有可用的Console依賴于底層平臺和JVM如何被調用。如果JVM是在交互式命令行(比如Windows的cmd)中啟動的,并且輸入輸出沒有重定向到另外的地方,那么就可以得到一個可用的Console實例?。

Console類:

?

示例代碼:

1 import java.io.Console; 2 3 public class Test { 4 public static void main(String[] args){ 5 Console console = System.console(); 6 if(console!=null){//判斷console是否可用 7 String user = new String(console.readLine("Enter user:")); //讀取整行字符 8 String pwd = new String(console.readPassword("Enter passowrd:")); //讀取密碼,密碼輸入時不會顯示 9 console.printf("User is:"+user+"/n"); 10 console.printf("Password is:"+pwd+"/n"); 11 }else{ 12 System.out.println("JVM無法使用當前的Console"); 13 } 14 } 15 }

在IntelliJ IDEA 中直接運行執行結果:

JVM無法使用當前的Console

在cmd里面直接 java Test 結果:紅色字體是輸入部分,密碼后面輸入默認是隱藏的

F:\test\>java Test Enter user:niannianjiuwang Enter passowrd: User is:niannianjiuwang/nPassword is:123456/n

?

對腳本語言的支持(如: ruby, groovy, javascript)

JDK6增加了對腳本語言的支持(JSR 223),原理上是將腳本語言編譯成字節碼,這樣腳本語言也能享用Java平臺的諸多優勢,包括可移植性,安全等,另外,由于現在是編譯成字節碼后再執行,所以比原來邊解釋邊執行效率要高很多。加入對腳本語言的支持后,對

Java語言也提供了以下好處。
1、許多腳本語言都有動態特性,比如,你不需要用一個變量之前先聲明它,你可以用一個變量存放完全不同類型的對象,你不需要做強制類型轉換,因為轉換都是自動的。現在Java語言也可以通過對腳本語言的支持間接獲得這種靈活性。
2、可以用腳本語言快速開發產品原型,因為現在可以Edit-Run,而無需Edit-Compile-Run,當然,因為Java有非常好的IDE支持,我 們完全可以在IDE里面編輯源文件,然后點擊運行(隱含編譯),以此達到快速開發原型的目的,所以這點好處基本上可以忽略。
3、通過引入腳本語言可以輕松實現Java應用程序的擴展和自定義,我們可以把原來分布在在Java應用程序中的配置邏輯,數學表達式和業務規則提取出來,轉用JavaScript來處理。

Sun的JDK6實現包含了一個基于Mozilla Rhino的 腳本語言引擎,支持JavaScript,這并不是說明JDK6只支持JavaScript,任何第三方都可以自己實現一個JSR-223兼容的腳本引擎 使得JDK6支持別的腳本語言,比如,你想讓JDK6支持Ruby,那你可以自己按照JSR 223的規范實現一個Ruby的腳本引擎類,具體一點,你需要實現 javax.script.ScriptEngine(簡單起見,可以繼承 javax.script.AbstractScriptEngine) 和 javax.script.ScriptEngineFactory 兩個接口。當然,在你實現自己的腳本語引擎之前,先到 scripting.dev.java.net project 這里看看是不是有人已經幫你做了工作,這樣你就可以直接拿來用。

Scripting API

Scripting API是用于在Java里面編寫腳本語言程序的API, 在Javax.script中可以找到Scripting API,我們就是用這個API來編寫JavaScript程序,這個包里面有一個ScriptEngineManager類,它是使用Scriptng API 的入口,ScriptEngineManager可以通過Jar服務發現(service discovery)機制尋找合適的腳本引擎類(ScriptEngine),使用Scripting API的最簡單方式只需下面三步
1、創建一個ScriptEngineManager對象
2、通過ScriptEngineManager獲得ScriptEngine對象
3、用ScriptEngine的eval方法執行腳本

示例代碼:?

1 import javax.script.Invocable; 2 import javax.script.ScriptEngine; 3 import javax.script.ScriptEngineManager; 4 5 public class Test { 6 public static void main(String[] args){ 7 ScriptEngineManager factory = new ScriptEngineManager(); 8 ScriptEngine engine = factory.getEngineByName("JavaScript"); 9 String script; 10 try { 11 script = "print('Hello')"; 12 engine.eval(script);// 執行腳本 13 script = "1-23*9/3+77"; 14 System.out.println(engine.eval(script).toString());// 不用對字符串做解析便可得到算式結果 15 engine.put("a", "一個字符串"); 16 script = "print(a)"; 17 engine.eval(script);// 腳本調用java對象 18 script = "function hello(name) { return 'Hello,' + name;}"; 19 engine.eval(script); 20 Invocable inv = (Invocable) engine; 21 System.out.println(inv.invokeFunction("hello", "Scripting"));//java調用腳本方法 22 } catch (Exception e) { 23 e.printStackTrace(); 24 } 25 } 26 27 }

輸出結果:

Hello 9 一個字符串 Hello,Scripting

?

?Common Annotations

?Common annotations原本是Java EE 5.0(JSR 244)規范的一部分,現在SUN把它的一部分放到了Java SE 6.0中。隨著Annotation元數據功能(JSR 175)加入到Java SE 5.0里面,很多Java 技術(比如EJB,Web Services)都會用Annotation部分代替XML文件來配置運行參數(或者說是支持聲明式編程,如EJB的聲明式事務), 如果這些技術為通用目的都單獨定義了自己的Annotations,顯然有點重復建設, 所以,為其他相關的Java技術定義一套公共的Annotation是有價值的,可以避免重復建設的同時,也保證Java SE和Java EE 各種技術的一致性。

下面列舉出Common Annotations 1.0里面的10個Annotations Common Annotations?

  • @Generated:生成的注釋用于標記已生成的源代碼。
  • @Resource: 用于標注所依賴的資源,容器據此注入外部資源依賴,有基于字段的注入和基于setter方法的注入兩種方式 。
  • @Resources: 同時標注多個外部依賴,容器會把所有這些外部依賴注入 。
  • @PostConstruct:標注當容器注入所有依賴之后運行的方法,用來進行依賴注入后的初始化工作,只有一個方法可以標注為PostConstruct 。
  • @RunAs:執行期間應用程序的角色 。
  • @PreDestroy:當對象實例將要被從容器當中刪掉之前,要執行的回調方法要標注為RunAs用于標注用什么安全角色來執行被標注類的方法,這個安全角色必須和Container 的Security角色一致的。
  • @RolesAllowed: 用于標注允許執行被標注類或方法的安全角色,這個安全角色必須和Container 的Security角色一致的 。
  • @PermitAll:允許所有角色執行被標注的類或方法 。
  • @DenyAll:不允許任何角色執行被標注的類或方法,表明該類或方法不能在Java EE容器里面運行 。
  • @DeclareRoles:用來定義可以被應用程序檢驗的安全角色,通常用isUserInRole來檢驗安全角色 。

注意:

  • RolesAllowed,PermitAll,DenyAll不能同時應用到一個類或方法上?
  • 標注在方法上的RolesAllowed,PermitAll,DenyAll會覆蓋標注在類上的RolesAllowed,PermitAll,DenyAll?
  • RunAs,RolesAllowed,PermitAll,DenyAll和DeclareRoles還沒有加到Java SE 6.0上來?
  • 處理以上Annotations的工作是由Java EE容器來做, Java SE 6.0只是包含了上面表格的前五種Annotations的定義類,并沒有包含處理這些Annotations的引擎,這個工作可以由Pluggable Annotation Processing API(JSR 269)來做
  • ?

    JDK6 改動最大的就是java GUI界面的顯示,JDK6支持最新的windows vista系統的Windows Aero視圖效果,而JDK5不支持。

    ?

    總結

    以上是生活随笔為你收集整理的JDK6 新特性的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。