JDK1.8與1.7的區別

轉自:http://www.2cto.com/kf/201307/225968.html

本文是我學習了解了jdk7和jdk8的一些新特性的一些資料,有興趣的大家可以瀏覽下下面的內容。

官方文檔:http://www.oracle.com/technetwork/java/javase/jdk7-relnotes-418459.html

在jdk7的新特性方面主要有下面幾方面的增強:

1.jdk7語法上

1.1二進制變量的表示,支持將整數類型用二進制來表示,用0b開頭。

// 所有整數 int, short,long,byte都可以用二進制表示

// An 8-bit 'byte' value:

byte aByte = (byte) 0b00100001;

// A 16-bit 'short' value:

short aShort = (short) 0b1010000101000101;

// Some 32-bit 'int' values:

intanInt1 = 0b10100001010001011010000101000101;

intanInt2 = 0b101;

intanInt3 = 0B101; // The B can be upper or lower case.

// A 64-bit 'long' value. Note the "L" suffix:

long aLong = 0b1010000101000101101000010100010110100001010001011010000101000101L;

// 二進制在數組等的使用

final int[] phases = { 0b00110001, 0b01100010, 0b11000100, 0b10001001,

0b00010011, 0b00100110, 0b01001100, 0b10011000 };

1.2? Switch語句支持string類型

public static String getTypeOfDayWithSwitchStatement(String dayOfWeekArg) {

String typeOfDay;

switch (dayOfWeekArg) {

case "Monday":

typeOfDay = "Start of work week";

break;

case "Tuesday":

case "Wednesday":

case "Thursday":

typeOfDay = "Midweek";

break;

case "Friday":

typeOfDay = "End of work week";

break;

case "Saturday":

case "Sunday":

typeOfDay = "Weekend";

break;

default:

throw new IllegalArgumentException("Invalid day of the week: " + dayOfWeekArg);

}

return typeOfDay;

}

1.3 Try-with-resource語句

注意:實現java.lang.AutoCloseable接口的資源都可以放到try中,跟final里面的關閉資源類似; 按照聲明逆序關閉資源 ;Try塊拋出的異常通過Throwable.getSuppressed獲取

try (java.util.zip.ZipFile zf = new java.util.zip.ZipFile(zipFileName);

java.io.BufferedWriter writer = java.nio.file.Files

.newBufferedWriter(outputFilePath, charset)) {

// Enumerate each entry

for (java.util.Enumeration entries = zf.entries(); entries

.hasMoreElements();) {

// Get the entry name and write it to the output file

String newLine = System.getProperty("line.separator");

String zipEntryName = ((java.util.zip.ZipEntry) entries

.nextElement()).getName() + newLine;

writer.write(zipEntryName, 0, zipEntryName.length());

}

}

1.4 Catch多個異常 說明:Catch異常類型為final; 生成Bytecode 會比多個catch小; Rethrow時保持異常類型

public static void main(String[] args) throws Exception {

try {

testthrows();

} catch (IOException | SQLException ex) {

throw ex;

}

}

public static void testthrows() throws IOException, SQLException {

}

1.5 數字類型的下劃線表示 更友好的表示方式,不過要注意下劃線添加的一些標準,可以參考下面的示例

long creditCardNumber = 1234_5678_9012_3456L;

long socialSecurityNumber = 999_99_9999L;

float pi = 3.14_15F;

long hexBytes = 0xFF_EC_DE_5E;

long hexWords = 0xCAFE_BABE;

long maxLong = 0x7fff_ffff_ffff_ffffL;

byte nybbles = 0b0010_0101;

long bytes = 0b11010010_01101001_10010100_10010010;

//float pi1 = 3_.1415F;????? // Invalid; cannot put underscores adjacent to a decimal point

//float pi2 = 3._1415F;????? // Invalid; cannot put underscores adjacent to a decimal point

//long socialSecurityNumber1= 999_99_9999_L;???????? // Invalid; cannot put underscores prior to an L suffix

//int x1 = _52;????????????? // This is an identifier, not a numeric literal

int x2 = 5_2;????????????? // OK (decimal literal)

//int x3 = 52_;????????????? // Invalid; cannot put underscores at the end of a literal

int x4 = 5_______2;??????? // OK (decimal literal)

//int x5 = 0_x52;??????????? // Invalid; cannot put underscores in the 0x radix prefix

//int x6 = 0x_52;??????????? // Invalid; cannot put underscores at the beginning of a number

int x7 = 0x5_2;??????????? // OK (hexadecimal literal)

//int x8 = 0x52_;??????????? // Invalid; cannot put underscores at the end of a number

int x9 = 0_52;???????????? // OK (octal literal)

int x10 = 05_2;??????????? // OK (octal literal)

//int x11 = 052_;??????????? // Invalid; cannot put underscores at the end of a number

1.6 泛型實例的創建可以通過類型推斷來簡化 可以去掉后面new部分的泛型類型,只用<>就可以了。

//使用泛型前

List strList = new ArrayList();

List strList4 = new ArrayList();

List>> strList5 =? new ArrayList>>();

//編譯器使用尖括號 (<>) 推斷類型

List strList0 = new ArrayList();

List>> strList1 =? new ArrayList>>();

List strList2 = new ArrayList<>();

List>> strList3 = new ArrayList<>();

List list = new ArrayList<>();

list.add("A");

// The following statement should fail since addAll expects

// Collection

//list.addAll(new ArrayList<>());

1.7在可變參數方法中傳遞非具體化參數,改進編譯警告和錯誤

Heap pollution 指一個變量被指向另外一個不是相同類型的變量。例如

List l = new ArrayList();

List ls = l;?????? // unchecked warning

l.add(0, new Integer(42)); // another unchecked warning

String s = ls.get(0);????? // ClassCastException is thrown

Jdk7:

public static void addToList (List listArg, T... elements) {

for (T x : elements) {

listArg.add(x);

}

}

你會得到一個warning

warning: [varargs] Possible heap pollution from parameterized vararg type

要消除警告,可以有三種方式

1.加 annotation @SafeVarargs

2.加 annotation @SuppressWarnings({"unchecked", "varargs"})

3.使用編譯器參數 –Xlint:varargs;

1.8 信息更豐富的回溯追蹤 就是上面try中try語句和里面的語句同時拋出異常時,異常棧的信息

java.io.IOException

§?????? at Suppress.write(Suppress.java:19)

§?????? at Suppress.main(Suppress.java:8)

§?????? Suppressed:? java.io.IOException

§?????????? at Suppress.close(Suppress.java:24)

§?????????? at Suppress.main(Suppress.java:9)

§?????? Suppressed:? java.io.IOException

§?????????? at? Suppress.close(Suppress.java:24)

§?????????? at? Suppress.main(Suppress.java:9)

2. NIO2的一些新特性

1.java.nio.file 和java.nio.file.attribute包 支持更詳細屬性,比如權限,所有者

2.? symbolic and hard links支持

3. Path訪問文件系統,Files支持各種文件操作

4.高效的訪問metadata信息

5.遞歸查找文件樹,文件擴展搜索

6.文件系統修改通知機制

7.File類操作API兼容

8.文件隨機訪問增強 mapping a region,locl a region,絕對位置讀取

9. AIO Reactor(基于事件)和Proactor

下面列一些示例:

2.1IO and New IO 監聽文件系統變化通知

通過FileSystems.getDefault().newWatchService()獲取watchService,然后將需要監聽的path目錄注冊到這個watchservice中,對于這個目錄的文件修改,新增,刪除等實踐可以配置,然后就自動能監聽到響應的事件。

private WatchService watcher;

public TestWatcherService(Path path) throws IOException {

watcher = FileSystems.getDefault().newWatchService();

path.register(watcher, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY);

}

public void handleEvents() throws InterruptedException {

while (true) {

WatchKey key = watcher.take();

for (WatchEvent event : key.pollEvents()) {

WatchEvent.Kind kind = event.kind();

if (kind == OVERFLOW) {// 事件可能lost or discarded

continue;

}

WatchEvent e = (WatchEvent) event;

Path fileName = e.context();

System.out.printf("Event %s has happened,which fileName is %s%n",kind.name(), fileName);

}

if (!key.reset()) {

break;

}

2.2 IO and New IO遍歷文件樹 ,通過繼承SimpleFileVisitor類,實現事件遍歷目錄樹的操作,然后通過Files.walkFileTree(listDir, opts, Integer.MAX_VALUE, walk);這個API來遍歷目錄樹

private void workFilePath() {

Path listDir = Paths.get("/tmp"); // define the starting file

ListTree walk = new ListTree();

…Files.walkFileTree(listDir, walk);…

// 遍歷的時候跟蹤鏈接

EnumSet opts = EnumSet.of(FileVisitOption.FOLLOW_LINKS);

try {

Files.walkFileTree(listDir, opts, Integer.MAX_VALUE, walk);

} catch (IOException e) {

System.err.println(e);

}

class ListTree extends SimpleFileVisitor {// NIO2 遞歸遍歷文件目錄的接口

@Override

public FileVisitResult postVisitDirectory(Path dir, IOException exc) {

System.out.println("Visited directory: " + dir.toString());

return FileVisitResult.CONTINUE;

}

@Override

public FileVisitResult visitFileFailed(Path file, IOException exc) {

System.out.println(exc);

return FileVisitResult.CONTINUE;

}

}

2.3 AIO異步IO 文件和網絡 異步IO在java

NIO2實現了,都是用AsynchronousFileChannel,AsynchronousSocketChanne等實現,關于同步阻塞IO,同步非阻塞IO,異步阻塞IO和異步非阻塞IO在ppt的這頁上下面備注有說明,有興趣的可以深入了解下。Java NIO2中就實現了操作系統的異步非阻塞IO。

// 使用AsynchronousFileChannel.open(path, withOptions(),

// taskExecutor))這個API對異步文件IO的處理

public static void asyFileChannel2() {

final int THREADS = 5;

ExecutorService taskExecutor = Executors.newFixedThreadPool(THREADS);

String encoding = System.getProperty("file.encoding");

List> list = new ArrayList<>();

int sheeps = 0;

Path path = Paths.get("/tmp",

"store.txt");

try (AsynchronousFileChannel asynchronousFileChannel = AsynchronousFileChannel

.open(path, withOptions(), taskExecutor)) {

for (int i = 0; i < 50; i++) {

Callable worker = new Callable() {

@Override

public ByteBuffer call() throws Exception {

ByteBuffer buffer = ByteBuffer

.allocateDirect(ThreadLocalRandom.current()

.nextInt(100, 200));

asynchronousFileChannel.read(buffer, ThreadLocalRandom

……

3. JDBC 4.1

3.1.可以使用try-with-resources自動關閉Connection, ResultSet, 和 Statement資源對象

3.2. RowSet 1.1:引入RowSetFactory接口和RowSetProvider類,可以創建JDBC driver支持的各種 row sets,這里的rowset實現其實就是將sql語句上的一些操作轉為方法的操作,封裝了一些功能。

3.3. JDBC-ODBC驅動會在jdk8中刪除

try (Statement stmt = con.createStatement()) {

RowSetFactory aFactory = RowSetProvider.newFactory();

CachedRowSet crs = aFactory.createCachedRowSet();

RowSetFactory rsf = RowSetProvider.newFactory("com.sun.rowset.RowSetFactoryImpl", null);

WebRowSet wrs = rsf.createWebRowSet();

createCachedRowSet

createFilteredRowSet

createJdbcRowSet

createJoinRowSet

createWebRowSet

4. 并發工具增強

4.1.fork-join

最大的增強,充分利用多核特性,將大問題分解成各個子問題,由多個cpu可以同時解決多個子問題,最后合并結果,繼承RecursiveTask,實現compute方法,然后調用fork計算,最后用join合并結果。

class Fibonacci extends RecursiveTask {

final int n;

Fibonacci(int n) {

this.n = n;

}

private int compute(int small) {

final int[] results = { 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89 };

return results[small];

}

public Integer compute() {

if (n <= 10) {

return compute(n);

}

Fibonacci f1 = new Fibonacci(n - 1);

Fibonacci f2 = new Fibonacci(n - 2);

System.out.println("fork new thread for " + (n - 1));

f1.fork();

System.out.println("fork new thread for " + (n - 2));

f2.fork();

return f1.join() + f2.join();

}

}

4.2.ThreadLocalRandon 并發下隨機數生成類,保證并發下的隨機數生成的線程安全,實際上就是使用threadlocal

final int MAX = 100000;

ThreadLocalRandom threadLocalRandom = ThreadLocalRandom.current();

long start = System.nanoTime();

for (int i = 0; i < MAX; i++) {

threadLocalRandom.nextDouble();

}

long end = System.nanoTime() - start;

System.out.println("use time1 : " + end);

long start2 = System.nanoTime();

for (int i = 0; i < MAX; i++) {

Math.random();

}

long end2 = System.nanoTime() - start2;

System.out.println("use time2 : " + end2);

4.3. phaser 類似cyclebarrier和countdownlatch,不過可以動態添加資源減少資源

void runTasks(List tasks) {

final Phaser phaser = new Phaser(1); // "1" to register self

// create and start threads

for (final Runnable task : tasks) {

phaser.register();

new Thread() {

public void run() {

phaser.arriveAndAwaitAdvance(); // await all creation

task.run();

}

}.start();

}

// allow threads to start and deregister self

phaser.arriveAndDeregister();

}

5. Networking增強

新增URLClassLoader close方法,可以及時關閉資源,后續重新加載class文件時不會導致資源被占用或者無法釋放問題

URLClassLoader.newInstance(new URL[]{}).close();

新增Sockets Direct Protocol

繞過操作系統的數據拷貝,將數據從一臺機器的內存數據通過網絡直接傳輸到另外一臺機器的內存中

6. Multithreaded Custom Class Loaders

解決并發下加載class可能導致的死鎖問題,這個是jdk1.6的一些新版本就解決了,jdk7也做了一些優化。有興趣可以仔細從官方文檔詳細了解

jdk7前:

Class Hierarchy:

class A extends B

class C extends D

ClassLoader Delegation Hierarchy:

Custom Classloader CL1:

directly loads class A

delegates to custom ClassLoader CL2 for class B

Custom Classloader CL2:

directly loads class C

delegates to custom ClassLoader CL1 for class D

Thread 1:

Use CL1 to load class A (locks CL1)

defineClass A triggers

loadClass B (try to lock CL2)

Thread 2:

Use CL2 to load class C (locks CL2)

defineClass C triggers

loadClass D (try to lock CL1)

Synchronization in the ClassLoader class wa

jdk7

Thread 1:

Use CL1 to load class A (locks CL1+A)

defineClass A triggers

loadClass B (locks CL2+B)

Thread 2:

Use CL2 to load class C (locks CL2+C)

defineClass C triggers

loadClass D (locks CL1+D)

7. Security 增強

7.1.提供幾種 ECC-based algorithms (ECDSA/ECDH) Elliptic Curve Cryptography (ECC)

7.2.禁用CertPath Algorithm Disabling

7.3. JSSE (SSL/TLS)的一些增強

8. Internationalization 增強 增加了對一些編碼的支持和增加了一些顯示方面的編碼設置等

1. New Scripts and Characters from Unicode 6.0.0

2. Extensible Support for ISO 4217 Currency Codes

Currency類添加:

getAvailableCurrencies

getNumericCode

getDisplayName

getDisplayName(Locale)

3. Category Locale Support

getDefault(Locale.Category)FORMAT? DISPLAY

4. Locale Class Supports BCP47 and UTR35

UNICODE_LOCALE_EXTENSION

PRIVATE_USE_EXTENSION

Locale.Builder

getExtensionKeys()

getExtension(char)

getUnicodeLocaleType(String

……

5. New NumericShaper Methods

NumericShaper.Range

getShaper(NumericShaper.Range)

getContextualShaper(Set)……

9.jvm方面的一些特性增強,下面這些特性有些在jdk6中已經存在,這里做了一些優化和增強。

1.Jvm支持非java的語言 invokedynamic 指令

2. Garbage-First Collector 適合server端,多處理器下大內存,將heap分成大小相等的多個區域,mark階段檢測每個區域的存活對象,compress階段將存活對象最小的先做回收,這樣會騰出很多空閑區域,這樣并發回收其他區域就能減少停止時間,提高吞吐量。

3. HotSpot性能增強

Tiered Compilation? -XX:+UseTieredCompilation 多層編譯,對于經常調用的代碼會直接編譯程本地代碼,提高效率

Compressed Oops? 壓縮對象指針,減少空間使用

Zero-Based Compressed Ordinary Object Pointers (oops) 進一步優化零基壓縮對象指針,進一步壓縮空間

4. Escape Analysis? 逃逸分析,對于只是在一個方法使用的一些變量,可以直接將對象分配到棧上,方法執行完自動釋放內存,而不用通過棧的對象引用引用堆中的對象,那么對于對象的回收可能不是那么及時。

5. NUMA Collector Enhancements

NUMA(Non Uniform Memory Access),NUMA在多種計算機系統中都得到實現,簡而言之,就是將內存分段訪問,類似于硬盤的RAID,Oracle中的分簇

10. Java 2D Enhancements

1. XRender-Based Rendering Pipeline -Dsun.java2d.xrender=True

2. Support for OpenType/CFF Fonts GraphicsEnvironment.getAvailableFontFamilyNames

3. TextLayout Support for Tibetan Script

4. Support for Linux Fonts

11. Swing Enhancements

1.? JLayer

2.? Nimbus Look & Feel

3.? Heavyweight and Lightweight Components

4.? Shaped and Translucent Windows

5.? Hue-Saturation-Luminance (HSL) Color Selection in JColorChooser Class

12. Jdk8 lambda表達式 最大的新增的特性,不過在很多動態語言中都已經原生支持。

原來這么寫:

btn.setOnAction(new EventHandler() {

@Override

public void handle(ActionEvent event) {

System.out.println("Hello World!");

}

});

jdk8直接可以這么寫:

btn.setOnAction(

event -> System.out.println("Hello World!")

);

更多示例:

public class Utils {

public static int compareByLength(String in, String out){

return in.length() - out.length();

}

}

public class MyClass {

public void doSomething() {

String[] args = new String[] {"microsoft","apple","linux","oracle"}

Arrays.sort(args, Utils::compareByLength);

}

}

13.jdk8的一些其他特性,當然jdk8的增強功能還有很多,大家可以參考http://openjdk.java.net/projects/jdk8/

用Metaspace代替PermGen

動態擴展,可以設置最大值,限制于本地內存的大小

Parallel array sorting 新APIArrays#parallelSort.

New Date & Time API

Clock clock = Clock.systemUTC(); //return the current time based on your system clock and set to UTC.

Clock clock = Clock.systemDefaultZone(); //return time based on system clock zone

long time = clock.millis(); //time in milliseconds from January 1st, 1970

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • Spring Cloud為開發人員提供了快速構建分布式系統中一些常見模式的工具(例如配置管理,服務發現,斷路器,智...
    卡卡羅2017閱讀 134,991評論 19 139
  • 1. Java基礎部分 基礎部分的順序:基本語法,類相關的語法,內部類的語法,繼承相關的語法,異常的語法,線程的語...
    子非魚_t_閱讀 31,778評論 18 399
  • Java經典問題算法大全 /*【程序1】 題目:古典問題:有一對兔子,從出生后第3個月起每個月都生一對兔子,小兔子...
    趙宇_阿特奇閱讀 1,916評論 0 2
  • 背景 一年多以前我在知乎上答了有關LeetCode的問題, 分享了一些自己做題目的經驗。 張土汪:刷leetcod...
    土汪閱讀 12,776評論 0 33
  • 4月26日的生日花,狗仔花。 狗仔花,綠衣膀大,寬幅的朔葉,開著粉里嵌紫,紫里嵌粉的花朵。全株不管在哪個部位,輕輕...
    冬林探花閱讀 1,469評論 0 1