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

คลาสซ้อนแบบ Static

กำหนดคลาสซ้อนแบบ static เป็นชนิดตัวช่วยที่เกี่ยวข้องกันโดยไม่อ้างอิงอินสแตนซ์ของคลาสภายนอก

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

คลาสซ้อนแบบสแตติก

คลาสซ้อนแบบสแตติกถูกกำหนดไว้ภายในคลาสอื่นโดยใช้คีย์เวิร์ด static คลาสนี้ไม่มีการอ้างอิงไปยังอินสแตนซ์ของคลาสที่ห่อหุ้ม แต่เป็นเพียงการจัดกลุ่มเชิงตรรกะไว้ด้วยกัน

การประกาศคลาสซ้อนแบบสแตติก

ใช้ชื่อคลาสภายนอกเพื่อเข้าถึงคลาสซ้อนจากภายนอก

class LinkedList<T> {
    private Node<T> head;

    // Static nested class — no outer instance reference
    private static class Node<T> {
        T data;
        Node<T> next;
        Node(T data) { this.data = data; }
    }

    public void addFirst(T item) {
        Node<T> node = new Node<>(item);
        node.next = head;
        head = node;
    }
}

การเข้าถึงจากภายนอก

อ้างอิงคลาสซ้อนแบบสแตติกสาธารณะเป็น OuterClass.InnerClass

class Builder {
    public static class Config {
        public final String host;
        public final int port;
        Config(String host, int port) {
            this.host = host; this.port = port;
        }
    }
}

Builder.Config config = new Builder.Config("localhost", 8080);
System.out.println(config.host + ":" + config.port); // localhost:8080

คลาสซ้อนแบบสแตติกกับคลาสภายใน

ข้อแตกต่างสำคัญคือ คลาสซ้อนแบบสแตติกไม่มีการอ้างอิงโดยปริยายไปยังอินสแตนซ์ภายนอก แต่คลาสภายใน (ที่ไม่ใช่สแตติก) มีการอ้างอิงดังกล่าว

class Outer {
    private int x = 10;

    // Static nested: no access to x
    static class StaticNested {
        void doSomething() {
            // System.out.println(x); // compile error — no outer reference!
            System.out.println("Static nested");
        }
    }

    // Inner class: has access to x
    class Inner {
        void doSomething() {
            System.out.println(x); // 10 — can access outer fields
        }
    }
}

รูปแบบ Builder กับคลาสซ้อนแบบสแตติก

รูปแบบ Builder แบบดั้งเดิมใช้คลาสซ้อนแบบสแตติก เพื่อให้ผู้เรียกไม่จำเป็นต้องมีอินสแตนซ์ภายนอกสำหรับสร้างตัวสร้าง

class Pizza {
    private final String size, crust;
    private final List<String> toppings;

    private Pizza(Builder b) {
        this.size = b.size; this.crust = b.crust; this.toppings = List.copyOf(b.toppings);
    }

    public static class Builder {
        private String size = "medium", crust = "thin";
        private List<String> toppings = new ArrayList<>();
        public Builder size(String s)    { this.size = s; return this; }
        public Builder crust(String c)   { this.crust = c; return this; }
        public Builder topping(String t) { this.toppings.add(t); return this; }
        public Pizza build()             { return new Pizza(this); }
    }
}

รายการใน Map

Map.Entry เป็นอินเทอร์เฟซซ้อนแบบสแตติกที่เป็นที่รู้จักกันดี ใช้สำหรับวนซ้ำคู่คีย์-ค่า

import java.util.*;

Map<String, Integer> scores = Map.of("Alice", 95, "Bob", 87, "Carol", 92);

for (Map.Entry<String, Integer> entry : scores.entrySet()) {
    System.out.printf("%-10s: %d%n", entry.getKey(), entry.getValue());
}

// Modern: using var
for (var entry : scores.entrySet()) {
    System.out.println(entry.getKey() + " -> " + entry.getValue());
}

การทดสอบด้วยคลาสซ้อนแบบสแตติก

ในการทดสอบหน่วย คลาสซ้อนแบบสแตติกสามารถเก็บชุดข้อมูลสำหรับการทดสอบหรือการใช้งานจำลองที่มีขอบเขตอยู่ภายในคลาสทดสอบ

class UserServiceTest {
    // Static nested fake/stub — no outer instance needed
    static class FakeUserRepository implements UserRepository {
        private final Map<Long, User> store = new HashMap<>();

        public void save(User u) { store.put(u.id(), u); }

        public Optional<User> findById(long id) {
            return Optional.ofNullable(store.get(id));
        }
    }

    // @Test methods use FakeUserRepository
    void testFindUser() {
        FakeUserRepository repo = new FakeUserRepository();
        // ...
    }
}

คลาสซ้อนแบบสแตติกสำหรับตรรกะโดเมน

จัดกลุ่มชนิดข้อมูลที่เกี่ยวข้องกันด้วยคลาสซ้อนแบบสแตติก เพื่อให้โมเดลโดเมนมีการจัดระเบียบที่ดีขึ้น

class Order {
    private final long id;
    private final List<LineItem> items;

    // Static nested — logically belongs to Order, no outer reference needed
    public static class LineItem {
        public final String sku;
        public final int quantity;
        public final double unitPrice;

        public LineItem(String sku, int qty, double price) {
            this.sku = sku; this.quantity = qty; this.unitPrice = price;
        }

        public double total() { return quantity * unitPrice; }
    }

    // ...
}

การเปรียบเทียบ: คลาสซ้อนแบบสแตติกกับคลาสระดับบนสุด

ควรใช้คลาสซ้อนแบบสแตติกเมื่อคลาสนั้นถูกใช้เฉพาะในบริบทของคลาสภายนอก ควรใช้คลาสระดับบนสุดเมื่อคลาสนั้นนำไปใช้ได้กว้างกว่า

คลาสซ้อนแบบสแตติกกับชนิดทั่วไป

คลาสซ้อนแบบสแตติกทำงานร่วมกับชนิดทั่วไปเช่นเดียวกับคลาสระดับบนสุด

class Pair<A, B> {
    // Static nested with its own type params
    public static class Mutable<X, Y> {
        public X first;
        public Y second;
        public Mutable(X first, Y second) {
            this.first = first; this.second = second;
        }
    }

    public static <X, Y> Mutable<X, Y> mutableOf(X x, Y y) {
        return new Mutable<>(x, y);
    }
}
Pair.Mutable<String, Integer> p = Pair.mutableOf("Alice", 30);
System.out.println(p.first + " is " + p.second); // Alice is 30

ประสิทธิภาพด้านหน่วยความจำ

คลาสซ้อนแบบสแตติกไม่มีการอ้างอิงไปยังอินสแตนซ์ภายนอก จึงช่วยหลีกเลี่ยงการเก็บออบเจ็กต์ภายนอกไว้ในหน่วยความจำโดยไม่ตั้งใจ ซึ่งอาจทำให้เกิดการรั่วไหลของหน่วยความจำในโครงสร้างที่มีอายุการใช้งานยาวนาน

ตรวจสอบความเข้าใจอย่างรวดเร็ว

อะไรคือข้อแตกต่างระหว่างคลาสซ้อนแบบสแตติกกับคลาสภายใน (ที่ไม่ใช่สแตติก)

สรุป: คลาสซ้อนแบบสแตติก

ประเด็นสำคัญ:

  • คลาสซ้อนแบบสแตติกจัดกลุ่มอยู่กับคลาสภายนอก แต่ไม่มีการอ้างอิงไปยังอินสแตนซ์ภายนอก
  • การเข้าถึงจากภายนอก: OuterClass.NestedClass
  • การไม่มีการอ้างอิงโดยปริยายช่วยป้องกันการเก็บอินสแตนซ์ภายนอกไว้ในหน่วยความจำโดยไม่ตั้งใจ
  • รูปแบบ Builder มักใช้คลาส Builder ซ้อนแบบสแตติก
  • Map.Entry เป็นอินเทอร์เฟซซ้อนแบบสแตติกที่เป็นที่รู้จักกันดี
  • ควรใช้คลาสซ้อนแบบสแตติกเมื่อคลาสภายในไม่จำเป็นต้องเข้าถึงอินสแตนซ์ภายนอก

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

บทเรียน “คลาสซ้อนแบบ Static” ฟรีหรือไม่

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

คุณจะเรียนรู้อะไรในบทเรียน “คลาสซ้อนแบบ Static”

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

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

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

บทเรียน “คลาสซ้อนแบบ Static” ใช้เวลานานแค่ไหน

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

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

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

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

  1. คลาสซ้อนแบบ Static
  2. คลาสภายในและการเข้าถึงคลาสภายนอก
  3. คลาสเฉพาะที่และคลาสนิรนาม
  4. การเลือกกลยุทธ์การซ้อนคลาสที่เหมาะสม
← กลับไปที่ Java Academy