January 5, 2017

Static Vs Instance

Q - Static နဲ့ Instance ကို အလွယ် ဘယ်လိုခွဲမလဲ


A - Java ကို လေ့လာကာစလူတွေ အမြဲတမ်းလိုလို ကြုံတွေ့တတ်တဲ့ မေးခွန်းတစ်ခုဖြစ်ပါတယ်။ ဒီမေးခွန်းကို ခွဲစိတ်ကြည့်မယ်ဆိုရင် အောက်ပါ မေးခွန်းလေးတွေ ထပ်ပြီးထွက်လာနိုင်ပါတယ်။

  1. Static ဆိုတဲ အဓိပ္ပါယ်နဲ့ Instance ဆိုတဲ့အဓိပ္ပါယ်
  2. ဘယ်လိုနေရာတွေမှာ Static နဲ့ Instance တို့ကိုခွဲပြီးရေးနိုင်လဲ
  3. ဘယ်လိုရေးရင် Static ဖြစ်ပြီး ဘယ်လိုရေးရင် Instance ဖြစ်သွားမလဲ
  4. Static နဲ့ Instance တွေကို ဘယ်လို Access လုပ်ကြမလဲ
  5. Static နဲ Instance တွေရဲ့ ထူးခြားချက်တွေကဘာတွေလဲ
  6. ဘယ်လိုနေရာမျိုးတွေမှာ Static ကို သုံးပြီး ဘယ်လိုနေရာမျိုးတွေမှာ Instance တွေကို သုံးရမလဲ 

Static ဆိုတဲ့အဓိပ္ပါယ် နဲ့ Instance ဆိုတဲ့အဓိပ္ပါယ်

တိုက်ရိုက်ပြန်ရင်တော့ Static ကို Dynamic မဟုတ်တဲ့အတွက် ကိန်းသေတွေလို့ပြောနိုင်မယ်။ ဒါပေမဲ့ ဒီနေရာမှာ ကတော့ Class နဲ့ ပတ်သက်တဲ့အရာတွေလို့ဆိုလိုနိုင်ပါတယ်။

ဒါဆိုရင် Class ကို ဘာလို့ရေးရတာလဲ။
  1. Object ဆောက်ဖို့၊ Object ရဲ့ State နဲ့ Behavior ကို သတ်မှတ်ပေးဖို့
  2. Utility အနေနဲ့ Function တွေကို ရေးသား အသုံးဖို့
Static ဆိုတာက Object အတွက်မဟုတ်ပဲ ဒုတိယ ရည်ရွယ်ချက်တွေကို ရေးသားတဲ့အခါမှာ Class ထဲမှာ ထားပြီး သုံးနိုင်တဲ့ Member တွေကို ဖေါ်ပြတဲ့နေရာမှာ အသုံးပြုပါတယ်။

Object တွေကို Instance တွေလို့လဲခေါ်လေ့ရှိပါတယ်။ ဒါ့ကြောင့် Instance ဆိုတာက Object နဲ့ဆိုင်တဲ့အရာတွေကို ဖေါ်ပြတဲ့အခါတွေမှာ သုံးပါတယ်။

ဒါ့ကြောင့် Instance Variable ဆိုရင် Object တွေနဲ့ ဆိုင်တဲ့ Variable တွေ ဖြစ်ပြီး Instance Method ဆိုရင် Object တွေမှာ သုံးလို့ရတဲ့ Method တွေလို့ မှတ်နိုင်ပါတယ်။

တနည်း Static Variable ဆိုရင် Class နဲ့ ဆိုင်တဲ့ Variable ဖြစ်ပြီး Object ဆောက်တဲ့အခါမှာ အဲ့ဒီအချက်အလက်တွေကို Object တစ်ခု ရဲ့ State အနေနဲ့ အသုံးပြုမှာ မဟုတ်ပါဘူး။ ပြီးတော့ Static Method တွေကလဲ Class ရဲ့ Utility Method တွေဖြစ်ကြပါတယ်။ ဒါ့ကြောင့် Class ကနေ အသုံးပြုရမှာ ဖြစ်ပါတယ်။

ဒီလိုမှတ်ရင်လဲရနိုင်တယ်။ Instance Member တွေရဲ့ Owner ဟာ Object ဖြစ်ပြီး Static Member တွေရဲ့ Owner ဟာ Class ဖြစ်ပါမယ်။


ဘယ်လိုနေရာတွေမှာ Static နဲ့ Instance တို့ကိုခွဲပြီးရေးနိုင်လဲ

Class ရဲ့ Member တွေမှာ Static နဲ့ Instance တို့ကို ခွဲပြီးရေးနိုင်တယ်။

ဒါဆို Class ရဲ့ Member တွေက ဘာတွေလဲ ဆိုတဲ့ မေးခွန်းက ပေါ်လာပြန်မယ်။ Class Body ထဲမှာ ရေးလို့ရတဲ့ အရာတွေဟာ အဲ့ဒီ Class ရဲ့ Member တွေ ဖြစ်ကြတယ်။ အဲ့ဒီနေရာမှာ Class ထဲမှာ ဘာတွေရေးလို့ရလဲ ဆိုတာကို မသိရင် Class Member တွေ ဘာတွေရှိတယ်ဆိုတာကို သိမှာ မဟုတ်ပြန်ဘူး။

Class ထဲမှာ ရေးလို့ရတာကတော့ အောက်ပါ အရာတွေဖြစ်ပါတယ်။
Members Static Instance Description
Variable Yes Yes
Methods Yes Yes
Constructors No Yes Object ဆောက်တဲ့အခါမှာသာ သုံးတဲ့အတွက် Static Constructor ဆိုတာမရှိပါဘူး
Nested Class Yes Yes
Nested Interface Yes Yes
Nested Enum Yes No Enum တွေဟာ Default Static Entity တွေ ဖြစ်တဲ့အတွက် Instance Enum ဆိုတာ မရှိပါဘူး။ အဲ့ဒီအတွက် Static Keyword ကို မရေးလဲ Static တွေ သာဖြစ်ကြပါတယ်

Nested Class, Interface နဲ့ Enum တွေကိုတော့ နောက်အခန်းတွေကျမှ ဆက်ပြီး ဖေါ်ပြသွားပါမယ်။ အခုတော့ ဘာတွေလဲလို့ မမေးပါနဲ့ ဦး။


ဘယ်လိုရေးရင် Static ဖြစ်ပြီး ဘယ်လိုရေးရင် Instance ဖြစ်သွားမလဲ

အလွယ်ပြောရမယ်ဆိုရင် Static ကော Instance ကော သတ်မှတ်နိုင်တဲ့ Member တွေမှာ static လို့ရေးထားရင် Static Member တွေဖြစ်ပြီး ဘာမှ မရေးထားရင် Instance Member တွေ ဖြစ်ကြတယ်။

တကယ်တော့ Class ကို ရေးရတဲ့ အဓိက ရည်ရွယ်ချက်ဟာ Object မှာပါတဲ့ State နဲ့ Behavior ကို Define လုပ်ပေးဖို့ဖြစ်တယ်။ အဲ့ဒီအတွက် Default အတိုင်းဆိုလို့ကတော့ Object အတွက်ကြီးပဲ ဖြစ်တယ်။ Object ရဲ့ State တွေအတွက် Variable တွေနဲ့ သတ်မှတ်ပေးတယ်။ အဲ့ဒီတော့ Default အတိုင်း ဆိုလို့ကတော့ Variable တွေဟာ Object ရဲ့ State အတွက် ဖြစ်တဲ့အတွက် Instance Variable တွေဖြစ်မှာပဲ။

Method တွေကလဲ Object တွေရဲ့ Behavior ကို သတ်မှတ်ဖို့ရေးတယ်။ အဲ့ဒီအတွက် Default အတိုင်းဆိုလို့ကတော့ Instance Method တွေ ဖြစ်နေမှာပါပဲ။

အဲ့ဒီ Default တန်ဖိုးတွေကို ပြင်ချင်တော့မှ၊ ဆိုလိုတာက Variable တွေ Method တွေဟာ Object အတွက်မဟုတ်ဘူး၊ Class ထဲမှာပဲ သုံးမှာပါလို့ ဖေါ်ပြနိုင်အောင် Static Modifier ကို သုံးပြီး ရေးသားရမှာ ဖြစ်ပါတယ်။
public class Person {

    // static variable
    static int count;

    // instance variable
    String name;

    // instance method
    public void showName() {
        System.out.println(name);
    }

    // static method
    public static void showStudentCount() {
        System.out.println(count);
    }
}
ဒါ့ကြောင့် Variable တွေ Method တွေရှေ့မှာ ဘာမှမပါရင် Instance တွေ ဖြစ်ကြပြီး static ပါရင် Static တွေဖြစ်တယ်လို့ ခွဲပြီး မှတ်နိုင်မှာ ဖြစ်ပါတယ်။


Static နဲ့ Instance တွေကို ဘယ်လို Access လုပ်ကြမလဲ

ဒီနေရာမှာ အရေးကြီးတာက Owner ဟာ ဘယ်ဟာလဲဆိုတာကို သိဖို့လိုအပ်ပါတယ်။ Static Members တွေရဲ့ Owner ဟာ Class ဖြစ်ပြီး Instance Member တွေရဲ့ Owner ဟာ Object ဖြစ်ပါတယ်။ Members တွေကို Access လုပ်တဲ့ အခါမှာ Class တစ်ခုထဲကနေ Access လုပ်တာနဲ့ အဲ့ဒီ Class ရဲ့ အပြင်ကနေ Access လုပ်တာဆိုပြီး ၂ မျိုးရှိနိုင်ပါလိမ့်မယ်။

Class တစ်ခုထဲကနေ Access လုပ်မယ်ဆိုရင်တော့ Owner ကို မရေးပဲနေလို့ရပါတယ်။ ဒါ့ကြောင့် Variable ပဲ ဖြစ်ဖြစ် Method ပဲဖြစ်ဖြစ် အဲ့ဒီအတိုင်းကို Access လုပ်နိုင်လိမ့်မယ်။ (ဒီနေရာမှာ Variable Hiding တို့ Super Class ထဲက Member တွေကိုသုံးချင်ရင်ကောတို့၊ ခေါ်လို့ရတာမရတာတို့ ရှိပါသေးတယ်။ ဒါတွေကိုတော့ နောက်အခန်းတွေကြမှ ဆက်ပြောကြရအောင်။)

အဲ့ဒီ Class ရဲ့ အပြင်ကနေ Access လုပ်မယ်ဆိုရင်တော့ Owner ကနေ တဆင့် Access လုပ်ရမှာ ဖြစ်ပါတယ်။ [Owner].[Member] ဆိုပြီး Access လုပ်ရမှာ ဖြစ်တယ်။ Variable တွေဆိုရင်တော့ owner.variable ဆိုပြီး ရေးရပါမယ်။ Method တွေဆိုရင်တော့ owner.method() ဆိုပြီးရေးရမှာပါ။ Method တွေကို Access လုပ်တဲ့အခါမှာတော့ Method Signature အတိုင်း Parameter တွေကို ရေးသားပေးရမှာ ဖြစ်ပါတယ်။
public class PersonTest {

    public static void main(String [] args) {

        // static variable
        Person.count = 10;

        // static method
        Person.showStudentCount();
    }
}

Person Class ထဲမှာ ပါတဲ့ count ဟာ Static Variable ဖြစ်တဲ့အတွက် Owner ဟာ Class ဖြစ်တဲ့အတွက် Class ကနေတဆင့် Access လုပ်ရမှာပါ။ ဒါ့ကြောင့် Person.count ဆိုပြီး ရေးရမှာ ဖြစ်ပါတယ်။ တဖန် showStudentCount() ဆိုတဲ့ Method ဟာလဲ Static Method ဖြစ်တဲ့အတွက် Person.showStudentCount() ဆိုပြီး Person Class ကနေတဆင့် ရေးသားရမှာ ဖြစ်ပါတယ်။
public class PersonTest {

    public static void main(String [] args) {

     Person p = new Person();

        // static variable
        p.name = "Thidar";

        // static method
        p.showName();
    }
}

Instance Member တွေကို Access လုပ်ချင်ပြီ ဆိုရင်တော့ Owner ဟာ Object ဖြစ်တဲ့အတွက် Object တွေကနေမှ ဆက်သွယ်လို့ရမှာပါ။ ဒါ့ကြောင် Person အမျိုးအစား ဖြစ်တဲ့ p variable နေရာမှာ new Person() ဆိုပြီး Object ဆောက်ပြီး သူ့ကို Reference အနေနဲ့ ပေးနေပါတယ်။

ပြီးတော့မှ instance variable ဖြစ်တဲ့ name ကို p.name ဆိုပြီး Access လုပ်ရမှာ ဖြစ်ပါတယ်။ အလားတူပဲ instance method ဖြစ်တဲ့ showName ကို Access လုပ်တဲ့အခါမှာလဲ onwer object ဖြစ်တဲ့ p ကနေတဆင့် p.showName() ဆိုပြီး Access လုပ်နေတာဖြစ်ပါတယ်။


Static နဲ Instance တွေရဲ့ ထူးခြားချက်တွေကဘာတွေလဲ

Static နဲ့ Instance တို့ရဲ့ ထူးခြားချက်တွေလို့ပြောလာရင် Class နဲ့ Object တို့ရဲ့ ထူးခြားချက်တွေလို ပြောလာတာနဲ့ အတူတူဖြစ်ပါလိမ့်မယ်။

အရင်ဆုံး Class ရဲ့ ထူးခြားချက်ဆိုတာကို ကြည့်အောင်။ Class တွေဟာ JVM တစ်ခုလုံးမှာ တစ်ခုထဲသာရှိပါမယ်။ Runtime ကနေ အလုပ်လုပ်နေရင်းနဲ့ Class တစ်ခုကို Declare လုပ်နေတာကို တွေ့ရင် JVM ရဲ့ Memory ပေါ်မှာ ရှိလားဆိုတာကို ကြည့်မယ်။ မရှိဘူးဆိုရင် Class Path ထဲကနေ အဲ့ဒီ Class ကို Memory ပေါ်ကို Load လုပ်ပါမယ်။ တကယ်လို့ ရှိပြီးသားဆိုရင်တော့ အဲ့ဒီ Class ကိုပဲ အသုံးပြုပါလိမ့်မယ်။ ဒါ့ကြောင့် Class တွေဟာ JVM ရဲ့ Memory ပေါ်မှာ တစ်ခုထဲသာ ရှိနေမှာ ဖြစ်ပါတယ်။

Object တွေကကော။ သူတို့တွေကတော့ new keyword နဲ Constructor ကို ခေါ်လိုက်တိုင်း Object အသစ်တစ်ခုကို တည်ဆောက်ပါတယ်။ အဲ့ဒီ Object တွေက တစ်ခုနဲ့ တစ်ခု ပတ်သက်မှူ့မရှိပါဘူး။ ကျွန်တော်တို့ Class တစ်ခုကနေ Object objectA နဲ့ objectB ကို တည်ဆောက်ခဲ့တယ်ဆိုပါစို့။ objectA မှာပါတဲ့ State တွေဟာ objectA နဲ့သာ ဆိုင်ပြီး objectB နဲ့ ပတ်သက်မှာ မဟုတ်ပါဘူး။

ဆက်ပြီး Object ကို Instantiate လုပ်တယ်ဆိုတာ JVM ပေါ်မှာ လက်တွေ့ ဘယ်လို ဖြစ်သွားလဲ ဆိုတဲ့ ဘက်ကနေ ကြည့်ကြရအောင်။ new keyword ကို သုံးပြီး Object ဆောက်ရင် JVM ပေါ်မှာ Class ကနေ Object နဲ့ ဆိုင်တဲ့ Instance Variable တွေကို Copy ကူးသွားပြီး Heap Memory ပေါ်မှာ Object ကို သွားဆောက်ပါတယ်။ Copy ကူးသွားတဲ့နေရာမှာ Static Variable တွေမပါပါဘူး။ Class နဲ့သာ ပတ်သက်တဲ့အရာတွေ ဖြစ်တဲ့ အတွက် Class ထဲမှာပဲ ချန်ထားခဲ့ပါတယ်။


ထူးခြားချက် တွေကို Variable တွေ ဘက်ကကြည့်ကြရအောင်။

Static Variable တွေဟာ Class ထဲမှာပဲ ရှိနေမှာဖြစ်ပြီး၊ Class ဟာလဲ JVM တစ်ခုလုံးမှာ တစ်ခုထဲသာရှိနေမှာ ဖြစ်တဲ့အတွက် သူတို့တွေဟာလဲ JVM ထဲမှာ တစ်ခုထဲသာ ရှိနေမှာပဲဖြစ်တယ်။ ဘယ်နေရာကပဲ Static Variable ကို Access လုပ်လုပ် တစ်ခုထဲသော အဲ့ဒီ Variable ရဲ့ တန်ဖိုးကိုပဲ ရရှိမှာ ဖြစ်ပါတယ်။

Instance Variable တွေကတော့ Object ဆောက်လိုက်တိုင်း Class ကနေ Copy ကူးသွားတာဖြစ်တဲ့အတွက် အဲ့ဒီ Object တစ်ခုချင်းစီနဲ့သာ ပတ်သက်ပါတယ်။ ဒါ့ကြောင့် Object တစ်ခုရဲ့ Instance Variable ကို တန်ဖိုးပြောင်းရင် အဲ့ဒီ Object ကပိုင်တဲ့ Instance Variable ရဲ့တန်ဖိုးသာ ပြောင်းသွားမှာ ဖြစ်တယ်။ တစ်ခြား Object တွေရဲ့ တန်ဖိုးဟာ ပြောင်းသွားမှာ မဟုတ်ပါဘူး။


Method တွေရဲ့ ထူးခြားချက်တွေကကောဘယ်လိုလဲ။

Static Method တွေဟာ Class တွေနဲ့သာဆိုင်တယ်။ အဲ့ဒါကြောင့် Static Method တွေကို Class တွေကနေတဆင့် Invoke လုပ်ကြမှာ ဖြစ်တယ်။ ဒီလို Static Method တွေကို Invoke လုပ်တဲ့ အချိန်မှာ Object တွေကို မဆောက်ရသေးတာလဲ ဖြစ်နိုင်တယ်။ ဆောက်ပြီးပြန်ရင်လဲ new ခေါ်တိုင်း Object ဆိုတာ ဆောက်လို့ရနေတဲ့ အတွက် Static Method ထဲကနေ Instance Variable ကို Access လုပ်ပါ၊ ဒါမှမဟုတ် Instance Method ကို Invoke လုပ်ပါလို့ ခိုင်းလာရင် ဘယ် Object ရဲ့ variable ကို ဘယ် Object ရဲ့ Method ကို Access လုပ်ရမှန်း သိနိုင်မှာ မဟုတ်ဘူး။

ဒါ့ကြောင့် Static Method တွေဟာ Static Variable တွေကိုသာ Access လုပ်နိုင်ပြီး Static Method တွေ အချင်းချင်းသာ Invoke လုပ်နိုင်မှာ ဖြစ်ပါတယ်။  Static Method တစ်ခုကနေ တစ်ခြား Method တစ်ခုကို Invoke လုပ်တော့မယ်ဆိုရင် အဲ့ဒီ Method ဟာ Static Method ဖြစ်နေဖို့လိုအပ်ပါတယ်။ Static Method ကနေ Instance Method ကို Invoke လုပ်ချင်ရင်တော့ Object ဆောက်ပြီးမှသာ Invoke လုပ်နိုင်မှာ ဖြစ်ပါတယ်။

Instance Method တွေကတော့ Object တွေကပိုင်တဲ့အတွက် Owner ဖြစ်တဲ့ Object တစ်ခုချင်းစီနဲ့ ပဲဆိုင်ပါတယ်။ ပြီးတော့ Instance Method တွေကနေ Instance Variable တွေကိုလဲ Access လုပ်နိုင်သလို Instance Method တွေကိုလဲ Invoke လုပ်နိုင်ပါတယ်။ သတိထားဖို့လိုတာက Owner Object ကနေ Instance ကို Invoke လုပ်လိုက်ရင် အဲ့ဒီ method ထဲကနေ Access လုပ်နေတဲ့ Instance Variable တွေရှိရင်လဲ အဲ့ဒီ Object ရဲ့ Variable ကိုပဲ Access လုပ်မှာ ဖြစ်ပြီး၊ တစ်ခြား Instance Method တွေကို Invoke လုပ်နေရင်လဲ အဲ့ဒီ​ Object ရဲ့ method ကိုပဲ Invoke လုပ်နေတာပဲ ဖြစ်ပါတယ်။ တစ်ခြား Object တွေနဲ့ ပတ်သက်မှူ့လုံးဝမရှိပါ။

တဖန် Instance Method ကနေ Static Variable တွေကိုလဲ Access လုပ်နိုင်ပြီး Static Method တွေကိုလဲ Invoke လုပ်နိုင်ပါတယ်။ ဘာလို့လဲ ဆိုတော့ Static Member တွေက Object မဆောက်ခင်ကထဲက Memory ပေါ်မှာ ရှိပြီးသားဖြစ်နေပြီး တစ်ခုထဲသာ ရှိတာဖြစ်တဲ့အတွက် ဘယ် Member ကို Access လုပ်မယ်ဆိုတာကို သိနေနိုင်တဲ့အတွက်ဖြစ်ပါတယ်။


Static နဲ့ Instance ကိုဘယ်လိုခွဲ သုံးရမလဲ

Static Members တွေနဲ့ Instance Members တွေရဲ့ ထူးခြားချက်ကို ကြည့်ရင် သိနိုင်ပါတယ်။ Static တွေဟာ Instance တွေလို Instance တစ်ခုချင်းစီအတွက် State တွေကို ပိုင်လို့မရဘူး။ ပြီးတော့ သူတို့တွေဟာ JVM ပေါ်မှာ တစ်ခုထဲရှိတဲ့ အရာတွေ ဖြစ်ကြတယ်။

အဲ့ဒီတော့ Static Method တွေကို State ပိုင်စရာမလိုအပ်တဲ့ Utility Function တွေမှာ ရေးသား အသုံးပြုနိုင်ပါတယ်။ တဖန် Static Variable တွေကလဲ JVM တစ်ခုလုံးမှာ တစ်ခုထဲသာရှိတဲ့ Variable တွေ ဖြစ်လာမှာ ဖြစ်တဲ့အတွက် Application တစ်ခုလုံးမှာ ဘုံအနေနဲ့ အသုံးပြုလိုတဲ့ အချက်အလက်တွေ၊ Object တွေကို Static Variable တွေအနေနဲ့ အသုံးပြုနိုင်ပါတယ်။

Static Variable ရဲ့ ထူးခြားချက်ကို အသုံးပြုပြီး Singleton Patterns လိုမျိုးကိုလဲ ရေးသားနိုင်ပါတယ်။ Disktop Application မျိုးမှာ Session ကို အသုံးပြုလို့မရဘူး။ အဲ့ဒီအစား Static Variable တွေကို Chache အနေနဲ့ ထားပြီး Data တွေကို Share လုပ်ပြီး အသုံးပြုနိုင်မှာ ဖြစ်ပါတယ်။

ဒါဖြင့် Instance Member တွေကကော။ ဒါကလွယ်ပါတယ်ဗျာ။ Object တစ်ခုချင်းစီမှာ ပိုင်ဆိုင်စေလိုတဲ့ State တွေ Behavior တွေဆိုရင် Instance Member တွေ သုံးပြီး ရေးလိုက်ရုံပေါ့ဗျာ။

မေးကြပါဗျာ။ ကြိုးစားပြီးဖြေသွားပါမယ်။
လေးစားစွာဖြင့်
မင်းလွင်

1 comment: