February 24, 2014

Project Coin 2

ကျွှန်တော်ပြီးခဲ့တဲ့ အပါတ်တုန်းက Java 7 ၏ ဘာသာရပ်ပိုင်းဆိုင်ရာ ပြုပြင်ပြောင်းလည်းမှု့ များကို ရေးသားနေခဲ့သော Project Coin နှင့် ၎င်း၏ ပြုပြင်ပြောင်းလည်းမှု့အချို့ကို ဖော်ပြခဲ့၏။ Coin အကြွေစေ့၊ အသေးသုံးဆိုသည့်အတိုင်း Java ပရိုဂရမ်မင်းဘာသာရပ် ရေးသားပုံ အစဉ်မပြေမှု့များကို ရေးသားနေသော ပရိုဂျက် ဖြစ်ပါသည်။ ယခုတစ်ခေါက် Java 7 တွင် Project Coin မှ ရေးသားခဲ့သော အသေးစားပြောင်းလည်းမှု့များမှာ အောက်ပါအတိုင်းဖြစ်၏။
  • switch ဝါကျများတွင် String ကို အသုံးပြုလာနိုင်ခြင်း
  • Diamond ပုံစံ ရေးသားမှု့များ
  • ကိန်းများ၏ရေးသားပုံပြောင်းလည်းခြင်းနှင့် ဘိုင်နရီဒေတာများကို ရေးသားလာနိုင်ခြင်း
  • Multi Catch နှင့် ပြန်လည် Throw လုပ်နိုင်ခြင်း
  • try-with-resources ရေးသားပုံ
  • Simplified varargs method invocation
အပေါ်မှ  အချက်၃ခုကို ပြီးခဲ့တဲ့ အပါတ်က ဖော်ပြပြီးဖြစ်ပါ၍၊ ယခုအပါတ်တွင်လည်း ဆက်လက်၍၊ ကျန်နေသေးသော အကြောင်းအရာများကို ဖော်ပြသွားပါဦးမည်။ ကျွှန်တော့်အနေနဲ့ကတော့ ဒီ Java 7 အရောက်မှာ သုံးရလွယ်လာတာကတော့ Multi Catch နဲ့ try-with-resources တို့ဖြစ်သည်ဟု ထင်ပါသည်။ ဆက်လက် လေ့လာသွားပါဦးမည်။


Multi Catch နှင့် ပြန်လည် Throw လုပ်နိုင်ခြင်း

Java ၏ Exception ထိမ်းသိမ်းမှု့သည် လွန်စွာမှ ရှုပ်ထွေးတတ်ပါသည်။ Java ကို စတင်လေ့လာခါစတွင် ဘာလို့ Java မှာ ဒီလောက် Exception တွေများရတာလဲဟု တွေးထင်ခဲ့ဘူးပါသည်။ လက်တွေ့ လုပ်ငန်းခွင် တွင်လည်း ယနေ့တိုင် ဒီ Exception ကို သေသေချာချာနားမလည်ပဲ ရေးသားထားသော ကုဒ်များကို မကြာမကြာတွေ့ရလေ့ရှိ၏။ ဤသို့ ရှုပ်ထွေးရခြင်း အကြောင်းအရင်းတွင် Java တွင် Exception တွေများလွန်းခြင်းနှင့် ထို Exception များကို တစ်ခုစီ ဖမ်းကာ ကွန်တရိုးများကို ရေးသားရန်လိုအပ်ခြင်း တို့ဖြစ်ပါသည်။

သို့ရာတွင် Java 7 အရောက်တွင် Exception များကို တပြိုင်နက်တည်း ဖမ်းစီး၍၊ ကွန်တရိုးများကို ရေးသားလာနိုင်ပါသည်။ Java 6 ၏ ရေးသားပုံဖြင့် jaxp ကို အသုံးပြုကာ xml ဖိုင်ကို ဖတ်၍ DOM အဖြစ် အသုံးပြုပုံကို ရေးသားကြည့်ပါမည်။
 public void doSample() {
  try {
   DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
   DocumentBuilder builder = factory.newDocumentBuilder();
   Document doc = builder.parse(new FileInputStream("file.xml"));
   
  } catch (ParserConfigurationException e) {
   e.printStackTrace();
  } catch (FileNotFoundException e) {
   e.printStackTrace();
  } catch (SAXException e) {
   e.printStackTrace();
  } catch (IOException e) {
   e.printStackTrace();
  }
 }
အထက်ပါအတိုင်း Document Object Model လေးတစ်ခုကို ရေးသားရန်အတွက် ဤမျှသော Exception များကို ကွန်တရိုးလုပ်ရန် လိုအပ်ခဲ့၏။ သို့ရာတွင် အထက်ပါ ပုံစံမျိုးတွင် Exception ဖြစ်ပေါ်လေ့ရှိသော အကြောင်းအရာများမှာ ခပ်ဆင်ဆင်ဖြစ်ပြီး၊ များသောအားဖြင့် ကွန်တရိုးများကို တူညီစွာ လုပ်ဆောင်လေ့ရှိ ကြသည်။

ဤနေရာတွင် အသုံးဝင်သည်က Multi Catch ဖြစ်၏။ Java 7 အရောက်တွင် အောက်ပါအတိုင်းရေးသား လာနိုင်ပါသည်။
 public void doSample() {
  try {
   DocumentBuilderFactory factory = DocumentBuilderFactory
     .newInstance();
   DocumentBuilder builder = factory.newDocumentBuilder();
   Document doc = builder.parse(new FileInputStream("file.xml"));

  } catch (ParserConfigurationException | SAXException | IOException e) {
   e.printStackTrace();
  }
 }
Exception များကို | ခံ၍ Block တစ်ခုတည်းတွင် ရေးသားလာနိုင်ပါသည်။ ထို့အပြင် FileNotFoundException သည် IOException ၏ Sub Class ဖြစ်သောကြောင့်၊ IOException ကို ရေးသားထားပါက၊ FileNotFoundException ကို ရေးသားရန် မလိုအပ်တော့ပေ။ Java 6 ထက်စာလျှင် ရေးသားထားသော ကုဒ်များမှာ နည်းပါးသွားပြီး၊ အတော်လေးကို အမြင်ရှင်းလာသည်ကို တွေ့ရပါလိမ့်မည်။ ရှင်းလင်းစွာ ရေးသားနိုင် ခြင်းသည်လည်း Bug များကို နည်းပါးစေနိုင်ပါသဖြင့်၊ လော့ဂျစ်ပိုင်းဆိုင်ရာမှာရော ရေးသားပုံအပေါ်မှာပါ တတ်နိုင်သလောက် ရှင်းလင်းစွာ ရေးသားရန် လိုအပ်လှပေသည်။

ထို့အပြင် Java 6 အထိ တစ်ခါဖမ်းထားသော Exception များကို ထိုအတိုင်း ပြန်လည် Throw မလုပ်နိုင်ခဲ့ပေမယ့် Java 7 အရောက်တွင် အောက်ပါအတိုင်းရေးသားပြီး၊ ပြန်လည် Throw လုပ်နိုင်လာပါမည်။
 public void doSample() throws FileNotFoundException, SAXException,
   IOException, ParserConfigurationException {
  try {
   DocumentBuilderFactory factory = DocumentBuilderFactory
     .newInstance();
   DocumentBuilder builder = factory.newDocumentBuilder();
   Document doc = builder.parse(new FileInputStream("file.xml"));

  } catch (final Exception e) {
   e.printStackTrace();
   throw e;
  }
 }
Java 6 အထိဆိုလျှင် မက်သတ်ရေးသားချိန်တွင် Throws လုပ်မည့် Exception များထဲတွင် ဖြည့်စွက်ရေးသားထားခြင်း မရှိပါက၊ အထက်ပါအတိုင်း ဖမ်းထားသော Exception ကို ထိုအတိုင်းပြန်ပြီး Throw လုပ်၍မရပေ။ ဤ Java 7 အရောက်တွင်၊ final စာလုံး တစ်လုံးဖြည့်စွက်ရုံနှင့် ထိုအတိုင်း ပြန်ပြီး Throw လုပ်နိုင်မည် ဖြစ်ပါသည်။


Try-With-Resources ရေးသားပုံ

File Stream များကို အသုံးပြုရာတွင်၊ Close လုပ်ဆောင်ချက်များကို ရေးသားရန်မှာ  အလွန် မေ့လွယ်လှပေသည်။ ထို့အပြင် Close လုပ်ဆောင်ချက်ကို ခေါ်ယူရာတွင် IOException ကို ဖြစ်ပေါ်စေတတ်ပါသဖြင့် ကုဒ်များကို ရေးသားရာတွင် အလွန်ရှည်ရှား တတ်ပေသည်။ ဖိုင်တစ်ခုကို ကော်ပီကူးသည့် ပရိုဂရမ်တစ်ခုကို ရေးသားကြည့်ပါမည်။
 public void copy(String pathFrom, String pathTo) {
  InputStream in = null;
  OutputStream out = null;
  
  try {
   in = new FileInputStream(pathFrom);
   out = new FileOutputStream(pathTo);
   byte[] buf = new byte[1024];
   int n;
   
   while((n = in.read(buf)) >= 0) {
    out.write(buf, 0, n);
   }
  } catch (IOException e) {
   System.err.println(e.getMessage());
  } finally {

   try {
    if(in != null)
     in.close();
    
    if(out != null)
     out.close();
    
   } catch (IOException e) {}
  }
 }
တကယ်တမ်းလိုအပ်သည်မှာ စာကြောင်း ၅ မှ ၁၆ အထိသာဖြစ်သော်လည်း၊ အောက်ပိုင်း စာကြောင်းများမှာ Close လုပ်ရန်အတွက် မဖြစ်မနေရေးသားရသော စာကြောင်းများဖြစ်ပါသည်။ သို့ရာတွင် Java 7 အရောက်တွင် အထက်ပါကုဒ်များကို ရေးသားရန်မလိုပဲ ရှင်းလင်းစွာရေးသားနိုင်ရန် ဖြစ်လာပါသည်။
 public void copy(String pathFrom, String pathTo) {
  
  try (InputStream in = new FileInputStream(pathFrom);
   OutputStream out = new FileOutputStream(pathTo)) {

   byte[] buf = new byte[1024];
   int n;
   
   while((n = in.read(buf)) >= 0) {
    out.write(buf, 0, n);
   }
  } catch (IOException e) {
   System.err.println(e.getMessage());
  }
 }
အထက်ပါအတိုင်း try ဝါကျအတွင်းတွင် အသုံးပြုမည့် Resource များကို ဖြည့်ရေးထားပါက၊ တကူးတက Close လုပ်ရန်မလိုအပ်တော့ပေ။ ထို့အပြင် Close လုပ်ရန်မလိုသည့်အတွက် Close လုပ်ခြင်းကြောင့် ဖြစ်ပွားတတ်သော Exception ကွန်တရိုး များကို တစ်ကူးတက ရေးသားရန်မလိုအပ်တော့ပေ။ ကုဒ်အချင်းချင်း ယှဉ်ကြည့်ရုံနှင့် မည်မျှရှင်းလင်းသွားသည်ကို တွေ့မြင်နိုင်ပါသည်။

ဤကဲ့သို့ Try-With-Resources ရေးသားပုံကို အကောင်းအထည်ဖော်နိုင်ရန်၊ Resource Object များတွင် java.lang.AutoCloseable အင်တာဖေစ်ကို ပံ့ပိုးပေးလာခဲ့ပါသည်။ AutoCloseable အင်တာဖေစ်၏ Sub Interface နှင့် ပံ့ပိုးထားသော ကလပ်စ်များမှာ အောက်ပါအတိုင်းဖြစ်၏။

  • java.beans.XMLDecoder
  • java.beans.XMLEncoder
  • java.io.Closeable
  • java.io.ObjectInput
  • java.io.ObjectOutput
  • java.sql.Connection
  • java.sql.ResultSet
  • java.sql.Statement
  • java.nio.channels.FileLock
  • javax.sound.midi.MidiDevice
  • javax.sound.midi.Receiver
  • javax.sound.midi.Transmitter
  • javax.sound.sampled.Line
အထက်ပါ ကလပ်စ်များနှင့် အင်တာဖေစ်များကို အသုံးပြုပါက၊ Close လုပ်ဆောင်ချက်ကို အတွင်းပိုင်းတွင် အလိုအလျှောက် လုပ်ဆောင်ပေးနိုင်မည် ဖြစ်သည်။ တဖန် AutoCloseable အတွက်လည်း Throable ကလပ်စ်အတွင်းတွင် addSupressed နှင့် getSupressed လုပ်ဆောင်ချက်များကို ဖြည့်စွက်လာတာကို တွေ့ရပါတယ်။


Simplified Varargs Method Invocation

Varargs များသည် J2SE 5.0 တွင် စတင်အသုံးပြုလာနိုင်ခဲ့သော၊ လွန်စွာမှ အသုံးဝင်သော ပုံစံတစ်မျိုး ဖြစ်ပါသည်။ သို့ရာတွင် Varargs များကို အသုံးပြုထားသော Method များကို အသုံးပြုရာတွ အခန့်မသင့်လျှင် ကွန်ပိုင်း Warning များထွက်ပေါ်တတ်ပေသည်။ Arrays#asList လုပ်ဆောင်ချက်သည် varargs ကို အသုံးပြုထားသော မက်သတ်တစ်ခုဖြစ်သည့်အတွက် နမှုနာအဖြစ် အသုံးပြုကြည့်ပါမည်။
package com.mmjug.java7.ep2;

import java.util.Arrays;
import java.util.List;

public class SimplifiedVaragsMethodInvocation {
 List<Integer> intList;
 List<List<String>> strListList;
 
 public void createArrays() {
  // No Warning
  intList = Arrays.asList(1,2,3,4);
  
  // Warning
  strListList = Arrays.asList(Arrays.asList("a","b","c"),
    Arrays.asList("a","b","c"));
 }
}
အထက်ပါကလပ်စ်ကို JDK 1.6 ဖြင့် ကွန်ပိုင်းလုပ်ကြည့်ပါက unchecked သတိပေးချက်ကို ဖြစ်ပေါ်စေမည် ဖြစ်ပါသည်။ သို့ရာတွင် JDK 1.7 ဖြင့် ကွန်ပိုင်းလုပ်ပါက ကွန်ပိုင်း သတိပေးချက် (Warning) မှာထွက်ပေါ်တော့မည် မဟုတ်ပါ။

ဘာကြောင့်လည်းဆိုတော့ Java 7 အရောက်တွင် ကွန်ပိုင်းထွက်သည့်နေရာကို Varargs များကို အသုံးသော Method များ၏ Warning များကို ခေါ်ယူသည့်နေရာမှ Method ရေးသားရာနေရာသို့ ရွှေ့ပြောင်းလိုက်ပြီး၊ ထိုမက်သတ်တွင် @SafeVarargs ဟု Anotation ကို ဖြည့်စွက်ရေးသားလိုက်ခြင်း ကြောင့်ဖြစ်၏။

ယခင်ကဆိုလျှင် Method ကို ခေါ်ယူသည့်နေရာတိုင်းတွင်@SuppressWarnings("unchecked") ဟု ရေးသားရန်ကိုအပ်ခဲ့ပြီး၊ Java 7 အရောက်တွင် Method ရှေ့တွင် @SafeVarargs ဟု တစ်ခါ ရေးသားထားပါက ခေါ်သည့်နေရာများတွင် အကြိမ်ကြိမ် ရေးသားရန် မလိုအပ်တော့ပါ။

ဘာပဲပြောပြော ခေါ်ယူသည့်နေရာတွင် လိုက်ရေးနေရသည် ထက်စာလျှင် တစ်နေရာတည်းတွင် ရေးသားလာနိုင်ခြင်းသည် ကုဒ်ရေးသားသူအနေဖြင့် လွန်းစွာမှ အစဉ်ပြေသော ပြောင်းလည်းမှု့ တစ်ခုဖြစ်ပါသည်။

Java 7 ၏ ဘာသာရပ်ပိုင်းဆိုင်ရာ ပြောင်းလည်းခြင်းများသည်၊ Java 5 ၏ Anotation နှင့် Generics များကဲ့သို့ ထင်ရှားသောပြောင်းလည်းခြင်းများဟု မဆိုနိုင်သော်လည်း၊ Java ကုဒ်များကို ရှင်းလင်းစွာရေးသားနိုင်ရန် အထောက်အကူပြုသော ပြောင်းလည်းမှု့များဟု သုံးသပ်မိပါသည်။ နောက်အပတ်များတွင် API ၏ ပြုပြင်ပြောင်းလည်းခြင်းများဖြစ်သော Java File API အသစ်အကြောင်းကို ဆက်လက်လေ့လာရင်း ဖော်ပြသွားပါဦးမည်။

ကိုးကား
http://itpro.nikkeibp.co.jp/article/COLUMN/20110425/359785/?ST=develop
http://www.docjar.com/html/api/java/util/Arrays.java.html


လေးစားစွာဖြင့်
မင်းလွင်

No comments:

Post a Comment