0Pricing
Java Academy · บทเรียน

ข้อควรระวังของ Autoboxing

กับดักจากการแปลงค่าว่างและ ==

ข้อควรระวังของ Autoboxing เป็นบทเรียน Java Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Java Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Java Academy มีบทเรียนทั้งหมด 4 บทเรียน

ความสะดวกมีข้อควรระวัง

การห่อหุ้มอัตโนมัติทำให้โค้ดกระชับขึ้น แต่ซ่อนการแปลงค่าที่อาจทำให้เกิดข้อผิดพลาดอย่างคาดไม่ถึง กับดักสำคัญสองประการคือการแกะห่อหุ้มค่าว่างและการเปรียบเทียบเอกลักษณ์ด้วย ==

บทเรียนนี้จะแสดงวิธีหลีกเลี่ยงทั้งสองกรณี

กับดักการแกะห่อหุ้มค่าว่าง

หากคลาสห่อหุ้มเก็บค่า null ไว้ แล้วคุณแกะห่อหุ้มเป็นชนิดข้อมูลพื้นฐาน Java จะทำให้เกิด NullPointerException

กรณีนี้พลาดได้ง่าย เพราะโค้ดดูเหมือนเป็นเพียงการกำหนดค่าธรรมดา

public class Main {
    public static void main(String[] args) {
        Integer maybe = null;
        try {
            int value = maybe;
            System.out.println(value);
        } catch (NullPointerException e) {
            System.out.println("Cannot unbox null!");
        }
    }
}

ค่าว่างในการคำนวณ

กับดักนี้ยังเกิดขึ้นภายในนิพจน์ได้ด้วย การนำคลาสห่อหุ้มที่มีค่า null มาบวกจะทำให้ Java แกะห่อหุ้มค่าก่อน และเกิดข้อยกเว้นก่อนที่การคำนวณจะเริ่มขึ้น

public class Main {
    public static void main(String[] args) {
        Integer count = null;
        try {
            int total = count + 5;
            System.out.println(total);
        } catch (NullPointerException e) {
            System.out.println("Null in arithmetic!");
        }
    }
}

การป้องกันค่าว่าง

ตรวจสอบคลาสห่อหุ้มว่าเป็น null หรือไม่ก่อนแกะห่อหุ้มเสมอ หรือกำหนดค่าเริ่มต้นไว้

public class Main {
    public static void main(String[] args) {
        Integer maybe = null;
        int safe = (maybe != null) ? maybe : 0;
        System.out.println(safe);
    }
}

ความประหลาดใจจากแคชของ ==

Integer.valueOf เก็บค่าตั้งแต่ -128 ถึง 127 ไว้ในแคช ดังนั้นค่าที่ถูกห่อหุ้มสองค่าในช่วงนี้อาจใช้ออบเจ็กต์เดียวกัน และ == จะคืนค่าเป็นจริง

public class Main {
    public static void main(String[] args) {
        Integer a = 100;
        Integer b = 100;
        System.out.println(a == b);
    }
}

นอกช่วงแคช

เมื่ออยู่นอกช่วงของแคช การห่อหุ้มแต่ละครั้งจะสร้างออบเจ็กต์ที่แตกต่างกัน คราวนี้ == จะเปรียบเทียบการอ้างอิงและคืนค่าเป็นเท็จ แม้ว่าตัวเลขจะมีค่าเท่ากัน

public class Main {
    public static void main(String[] args) {
        Integer a = 200;
        Integer b = 200;
        System.out.println(a == b);
    }
}

ใช้ equals เสมอ

เนื่องจาก == บนชนิดห่อหุ้มจะเปรียบเทียบว่าเป็นออบเจ็กต์เดียวกันหรือไม่ คุณจึงต้องใช้ .equals() เพื่อเปรียบเทียบค่าตัวเลขจริง

public class Main {
    public static void main(String[] args) {
        Integer a = 200;
        Integer b = 200;
        System.out.println(a.equals(b));
    }
}

การใช้ == ร่วมกับชนิดข้อมูลพื้นฐาน

หากด้านใดด้านหนึ่งของ == เป็นชนิดข้อมูลพื้นฐาน Java จะแกะค่าจากชนิดห่อหุ้มโดยอัตโนมัติ ดังนั้นจึงเปรียบเทียบกันตามค่า วิธีนี้เชื่อถือได้ แต่ยังคงทำให้เกิดข้อผิดพลาดได้หากชนิดห่อหุ้มมีค่าเป็นค่าว่าง

public class Main {
    public static void main(String[] args) {
        Integer a = 200;
        int b = 200;
        System.out.println(a == b);
    }
}

การห่อหุ้มที่ซ่อนอยู่ในลูป

การประกาศตัวสะสมของการวนซ้ำเป็นชนิดห่อหุ้มจะสร้างออบเจ็กต์ใหม่ในการวนซ้ำทุกครั้ง ด้านล่างนี้ หากใช้ Long แทน long ระบบจะห่อหุ้มค่าซ้ำ ๆ ควรเลือกใช้ชนิดข้อมูลพื้นฐาน

public class Main {
    public static void main(String[] args) {
        long sum = 0;
        for (int i = 0; i < 1000; i++) {
            sum += i;
        }
        System.out.println(sum);
    }
}

Map.get คืนค่าค่าว่าง

ข้อผิดพลาดที่พบได้บ่อยในงานจริงคือ Map.get จะคืนค่า null เมื่อไม่พบคีย์ การแกะค่าผลลัพธ์นั้นมาเป็น int จะทำให้เกิดข้อผิดพลาด ควรใช้ getOrDefault แทน

import java.util.HashMap;
import java.util.Map;

public class Main {
    public static void main(String[] args) {
        Map<String, Integer> scores = new HashMap<>();
        int score = scores.getOrDefault("missing", 0);
        System.out.println(score);
    }
}

การใช้งานอย่างปลอดภัย

แนวปฏิบัติสองข้อช่วยป้องกันข้อผิดพลาดจากการห่อหุ้มอัตโนมัติได้เกือบทั้งหมด ได้แก่ อย่าแกะค่าที่อาจเป็น null และเปรียบเทียบค่าชนิดห่อหุ้มด้วย .equals() แทน == เสมอ

ตรวจสอบอย่างรวดเร็ว

ทดสอบความเข้าใจเกี่ยวกับข้อผิดพลาดที่อาจเกิดจากการห่อหุ้มอัตโนมัติ

ทบทวน

คุณได้เรียนรู้ข้อผิดพลาดสำคัญจากการห่อหุ้มอัตโนมัติ:

  • การแกะค่าชนิดห่อหุ้มที่เป็น null จะทำให้เกิด NullPointerException
  • ป้องกันด้วยการตรวจสอบค่าว่างหรือใช้ค่าเริ่มต้น
  • == บนชนิดห่อหุ้มจะเปรียบเทียบการอ้างอิง โดยมีการเก็บค่าที่ใช้ซ้ำตั้งแต่ -128 ถึง 127
  • ใช้ .equals() เพื่อเปรียบเทียบค่าเสมอ
  • ใช้ getOrDefault เพื่อหลีกเลี่ยงค่าว่างจากการค้นหาในแผนที่

คำถามที่พบบ่อย

บทเรียน “ข้อควรระวังของ Autoboxing” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “ข้อควรระวังของ Autoboxing” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Java Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Java Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “ข้อควรระวังของ Autoboxing”

กับดักจากการแปลงค่าว่างและ == คุณปฏิบัติ Java Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Java Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน Java Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน

บทเรียน “ข้อควรระวังของ Autoboxing” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน Java Academy นี้ได้ไหม

ได้ บทเรียน Java Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. ชนิดข้อมูลพื้นฐานเทียบกับชนิดห่อหุ้ม
  2. Autoboxing และ Unboxing
  3. การแยกวิเคราะห์และ Valueof
  4. ข้อควรระวังของ Autoboxing
← กลับไปที่ Java Academy