[JAVA] Pass By ?

ปัญหานี้น่าจะเป็นปัญหาที่โลกแตกพอสมควรครับ และเป็นเรื่องที่ควรรู้ และเข้าใจครับ ไม่งั้น เวลาเจอ Defect อยู่ๆข้อมูลเปลี่ยนเฉย ผีหลอก หรือป่าว ไม่ใช่ครับ เราอาจจะเข้าใจผิดมาตลอด ตอนเรียน 2 ปีแรกที่มหาวิทยาลัย สิ่งที่ผมเข้าใจเกี่ยวกับ pass by ของ Java คือ

  • พวก Primitive Data Type เป็นการ Pass by Value ครับ
  • พวก Reference Type อย่าง Object เป็นการ Pass by Reference

pass-by-reference-vs-pass-by-value-animation

แต่ที่ผมเข้าใจมาผิดหมดครับ มารู้จริงๆ ตอนฝึกงานครับ เจอคำถามของพี่เลี้ยงไปจุกครับ พี่เลี้ยงเค้าบอกว่า Java ไม่ว่าเป็น Primitive Data Type หรือ Reference Type มีการ Pass by Value เท่านั้นครับ หลายคนน่าจะงงกัน มาลองดูกันครับ

  • Primitive Data Type Pass by Value ไม่น่าจะงงกัน
  • Reference Type อย่าง Object นี่ คือ Java ไม่ได้ Pass by Reference ตรงๆ แต่ Pass Reference Type by Value เอาง่ายๆ Copy Reference ครับ ลองดูจากตัวอยาง Code ได้ครับ
    package com.debuggingsoft.testpassby;
    
    public class TestPassbyReference {
    
    	public static void main(String[] args) {
    		   // TODO Auto-generated method stub
    		   Company company = new Company();
    		   company.setCompanyName("COMSWU");
    		   System.out.println("First >> " + company.getCompanyName());
    		   ChangeNameVer1(company);
    		   System.out.println("Second >> " + company.getCompanyName());
    		   ChangeNameVer2(company);
    		   System.out.println("Third >> " + company.getCompanyName());
    		   ChangeNameVer3(company);
    		   System.out.println("Fourth >> " + company.getCompanyName());
    	}
    	
    	public static void ChangeNameVer1(Company pCompany)
    	{
    		   pCompany.setCompanyName("DebuggingSoft");
    	}
    	
    	public static void ChangeNameVer2(Company pCompany)
    	{
    		   pCompany = new Company();
    		   pCompany.setCompanyName("Chatri Soft");
    	}
    	
    	public static void ChangeNameVer3(Company pCompany)
    	{
    		   pCompany = null;
    	}
    }
    

    จาก Code ลองมาดูผลลัพธ์กันครับ ผมจะ Prove ว่าถ้ามัน Pass by Reference จริงๆ แล้วค่าต้องเปลี่ยนครับ จากการทดสอบของผมครับได้ผลลัพธ์ ดังนี้
    2016-06-20_230209

    • Step 1 : ChangeNameVer1 ผมแก้ชื่อ Company ครับ เมื่อ Console แสดงผลลัพธ์เป็นไปตามที่ผมแก้ครับ คือ "DebuggingSoft"
    • Step 2 : ChangeNameVer2 คราวนี้ผมเพิ่มลูกเล่นไปอีกนิดครับ New ใหม่ในนั้น แล้วทำการ Set ค่าใหม่ ผลปรากฏว่า ยังเป็น "DebuggingSoft" นั้นแหละ แสดงว่า Java Pass by Value ถ้า Pass by Reference แล้วค่าต้องเปลี่ยนครับ
    • Step 3 : ChangeNameVer3 ผมยัด Null ให้เลยครับ ถ้ามันต้องขึ้น Exception ที่เราๆคุ้นเคยกันครับ

      java.lang.NullPointerException

      แต่มันไม่แสดงนี่สิ แสดงว่า Java Pass by Value ถ้า Pass by Reference แล้วค่าต้องเปลี่ยนครับ

หลังจากเข้าใจแล้ว ว่าแต่ทำไม Java ถึงมีแต่ Pass by Value ทั้งหมด !!! คงต้องกลับไปตอนเรียนวิชา CP121 ไม่ใช่สิ ต้อง CP111 วิชา Programming I ภาษา C นั้นเองครับ ตัวภาษาตระกูล C มันมี ของแสบอย่างหรือครับ คือ Pointer เรามาดูดีกว่าว่าภาษา C Pass by ?

  • Paas by Value
  • Pass Pointer by Value : Concept เดียวกับ Java ครับ เอา Pointer ส่งเป็น By Value แทนครับ

ต่อไปขยับอีกนิดเป็น C++

  • Pass by Value
  • Pass Pointer by Value
  • Pass by Reference

แต่สิ่งที่ C กับ C++ มีปัญหาเหมือนกัน คือ พวก Pointer, Reference ที่เราต้องจัดการ Memory เอง ใช้แล้วอย่าลืม Free ไม่งั้นบึ้มมมมม  ลองอ่าน Link นี้ดูใน isocpp.org  จะเข้าใจว่าทำไม C++ ถึงให้ Pointer กับ Reference มาให้ครับ ใน Java เองมี Pointer แอบซ่อน เราไม่ต้องรู้หรอก รู้แค่่มันใช้งานได้ มีตัวตนใน NullPointerException ก็พอครับ 555

ถัดมาคงเปลี่ยนเรื่องของความปลอดภัย ถ้าให้จัดการกับ Reference ตรงๆ เราอาจจะสามารถยุ่งเข้าไปในหน่วยความจำได้ครับ

สุดท้าย By Design - Keep it Simple ครับ ผมขอยกคำของคุณ James Gosling, et al., The Java Programming Language, 4th Edition ครับ

Some people will say incorrectly that objects are passed "by reference." In programming language design, 
the term pass by reference properly means that when an argument is passed to a function, 
the invoked function gets a reference to the original value, not a copy of its value. If the function modifies its parameter,
 the value in the calling code will be changed because the argument and parameter use the same slot in memory.... 
The Java programming language does not pass objects by reference; it passes object references by value. 
Because two copies of the same reference refer to the same actual object, 
changes made through one reference variable are visible through the other. 
There is exactly one parameter passing mode -- pass by value -- 
and that helps keep things simple. 
-- James Gosling, et al., The Java Programming Language, 4th Edition

Reference:


Discover more from naiwaen@DebuggingSoft

Subscribe to get the latest posts sent to your email.