ของเล่นใหม่ใน Java 7

duke_java7
 
เป็น major version อันแรกของ Java ใต้ร่มเงาของ Oracle! ผมเองไม่ได้เขียน Java มานานมากๆแล้วเพราะงานที่ทำงานไม่ได้ใช้ตรงๆ แต่ก็ตื่นเต้นไปกับของเล่นใหม่ๆด้วย วันนี้เลยลอง Netbeans 7 + JDK 7 มาเล่นปัดฝุ่นดู 😀

เข้าใจว่ามันมีของใหม่เติมเข้ามาในเวอร์ชันนี้เยอะ แต่ที่ลองเล่นไปจะเป็นอะไรที่เกี่ยวกับตัวภาษาตรงๆ:

Binary Literals

ให้เราแทนค่าที่เป็น binary เช่น 01010101 ลงไปใน code ได้ตรงๆ น่าจะมีประโยชน์มากกับคนที่ทำพวก network / protocol / data format programming ที่แบบว่าต้องเซ็ตบิตที่ตำแหน่งเท่านี้เท่านั้นเยอะๆ ทำให้โค้ดอ่านง่ายขึ้นด้วย (รึเปล่า ??)

int data = 0b001;
int mask = 0b101;
data |= mask;

System.out.println("Data: " + Integer.toBinaryString(data));
// prints 'Data: 101'

Underscores in Numeric Literals

เป็นเรื่อง readability คือพวกค่าที่เป็นตัวเลขก็เอา underscore ไปคั่นได้ ทำให้อ่านง่ายขึ้น (เหรอ?) เช่น

int mask = 0b1110_1010;
int colorCode = 0xFF_FF_CC;
double myAccountBalance = 3_141_592.654;

Strings in switch Statements

อันนี้ไม่มีอะไรต้องอธิบาย เป็น feature ที่ถูกขอมานานถึง 16 ปีแล้ว!

มีเรื่องที่น่าสนใจอีกเรื่อง ถ้าใครตั้งใจเรียนสมัยอยู่มหาลัยจะรู้ว่า switch กับ if ซ้อนกันหลายๆอันมันทำงานไม่เหมือนกัน (ในเชิงทฤษฎี) ในเชิงปฎิบัติ หนังสือเกี่ยวกับ JVM เล่มนี้เค้าบอกว่า ถ้า constants ใน case ต่างๆทั้งหมดรวมกันแล้วมันโล่งเตียน (Sparse) คือมันกระจายตัวกันมากๆ Java จะใช้ Binary search แทนการใช้ Offset table (แบบที่เราเข้าใจตอนเรียน) แต่ถ้าอยู่กันหนาแน่น ก็จะใช้ Offset Table ตามปกติ .. เป็น optimization อย่างนึง

Type Inference for Generic Instance Creation

เป็นการแนะนำตัวของ diamond (“<>”) ช่วยให้เวลาประกาศพวก Generic เขียนง่ายขึ้น ไม่รกหูรกตา

List<String> nameList = new ArrayList<>() {};
Map<Integer, List<String>> customerToOrders = new HashMap<>();

The try-with-resources Statement

ผมว่าอันนี้มีประโยชน์เยอะเลย น่าจะทำให้โค้ด Java ใหม่ๆเปลี่ยนไปเยอะ

ถ้าให้อธิบายแบบผมคือ มันเป็นเป็นใช้ syntax ของภาษาที่บังคับให้ทำอะไรซักอย่างก่อนออกจาก scope เสมอๆ (คล้ายๆกับ destructor ของ C++ ที่จะโดนเรียกเสมอตอนออกจาก scope, เอาไปทำเทคนิคที่เรียกว่า RAII ได้)

ตัวอย่างที่ยกมาให้ดูในเว็บของ Java เป็นการใช้ BufferedReader แต่ไม่ต้องมีการสั่ง close() เอง ทำให้โค้ดอ่านง่ายขึ้นเยอะเลย จริงมั้ย??

try (BufferedReader br = new BufferedReader(new FileReader(path))) {
return br.readLine();
}
// br is auto-closed here!

ใน Java 7 ก็มีหลาย class นอกจาก BufferedReader ที่สนับสนุน try-with-resources แบบนี้ ถ้าเราอยากจะให้ Class ของเราสนับสนุน try แบบนี้ด้วย ก็แค่ implements AutoCloseable

class TestAutoCloseable implements AutoCloseable{

@Override
public void close() throws Exception {
System.out.println("== Close ==");
}
}

// ...

try(TestAutoCloseable ac = new TestAutoCloseable()){
// Doing something ..
System.out.println("== Inside try ==");
}catch(Exception ex){ // (you don't want to do this)
// Close failed!
}
System.out.println("== Outside try ==");

// Prints:
// == Inside try ==
// == Close ==
// == Outside try ==

Catching Multiple Exception Types and Rethrowing Exceptions with Improved Type Checking

อันนี้มีสองอย่าง

อย่างแรกคือ catch Exception ได้หลายๆแบบ (ยิงปืนนัดเดียวได้นกหลายตัว) โดยใช้ try{ .. } catch(FirstException | SecondException ex){ .. }

อย่างที่สองคือ Improved Type Checking คือ Java 7 ฉลาดขึ้นสามารถเข้าใจ Type ของ Exception ได้ละเอียดขึ้น ในตัวอย่างที่ยกมา:

public void rethrowException(String exceptionName)
throws FirstException, SecondException {
try {
if (exceptionName.equals("First")) {
throw new FirstException();
} else {
throw new SecondException();
}
}
catch (Exception e) {
throw e;
}
}

จะเห็นได้ว่าถึงแม้ใน catch จะ thorw e (ที่มี type เป็น Exception) แต่ปรากฎว่าที่หัว method เราเขียน throws FirstException, SecondException ซึ่งเป็น type ที่ specific กว่าได้! อันนี้ทำได้เพราะ Java ฉลาดพอที่จะเข้าใจได้ว่า code ใน try มัน throw  อะไรออกมาได้บ้าง

Improved Compiler Warnings and Errors When Using Non-Reifiable Formal Parameters with Varargs Methods

อ่านหัวข้อก็รู้แล้วว่าอันนี้เข้าใจยากแน่ๆ! = =’ (เลยเอาไว้หัวข้อสุดท้าย)  อันนี้ผมอ่านแล้วก็ยังงงๆ เลยไม่กล้าลงรายละเอียด

โดยสั้นๆคือ code แบบนี้มันถูก syntax และ compile ผ่าน แต่จะตายตอนรัน

List l = new ArrayList<Number>();
List<String> ls = l; // unchecked warning
l.add(0, new Integer(42)); // another unchecked warning
String s = ls.get(0); // ClassCastException is thrown

Java 7 มีการพัฒนาในการระแวดระวังความผิดพลาดทำนองนี้ โดยการเพิ่ม Warning และ Errors ให้ผู้ใช้ระวังตัวนั่นเอง (รากหญ้าแบบผมคงไม่เจอปัญหาทำนองนี้บ่อยๆ = =’)

..

โดยสรุปว่าผม try-with-resources เป็น highlight ของอันนี้ ถ้าเอาไปเทียบกับ C# มันคือ using(..) statement นั่นเอง

แต่ที่ดูแล้วน่าคิดอีกเรื่องคือเรื่อง throw error ได้ละเอียดขึ้น อันนี้ถ้าไม่ใช้ Checked Exception ตั้งแต่แรกก็จะไม่มีปัญหานี้เลย (เหมือนใน C#)

ชอบ features ไหนกันบ้าง ? อ่านละเอียดๆได้ที่ http://download.oracle.com/javase/7/docs/technotes/guides/language/enhancements.html#javase7

6 thoughts on “ของเล่นใหม่ใน Java 7

  1. กร

    เยี่ยมเลย แต่ผมนึกว่าคุณจะเปรียบ try-with กับ with ของ python ซะอีก ดันไปเปรียบกับ C# ซะได้

    Reply
  2. m3rlinezxxx

    @korn เขียน Python มายังไม่เคยใช้ with เลย – -‘ มึงไม่บอกก็คงไม่รู้ว่ามันเป็นเรื่องเดียว แต่ binary literal นั่น Python มีนะ

    Reply
  3. m3rlinez

    @tap Oh! ก่อนหน้านี้เทสต์อะไรซักอย่างอยู่อ่ะ ลืมเอาออก – -‘a

    Reply
  4. wiennat

    ท่ีบ้าอีกเรื่องคือ

    Java 7 แต่เลขเวอร์ชันเจือกเป็น 1.7
    ตอน Java 6 เลขเวอร์ชันก็เป็น 1.6
    – -"

    Reply
  5. plynoi

    @wiennat : มันเป็นเลขสำหรับ Geek กับ Management ครับ
    คือ Geek จะเรียกว่า Java 7 Java 6 ซึ่ง Management และ Sale จะไม่เข้าใจ จะเข้าใจแค่ 1.7 1.6

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *