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

ฟิลด์แบบ Static และค่าคงที่

ใช้ฟิลด์แบบ static สำหรับสถานะร่วม ค่าคงที่ด้วย static final และตัวเริ่มต้นแบบ static

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

ฟิลด์สแตติกและค่าคงที่

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

ฟิลด์สแตติกกับฟิลด์อินสแตนซ์

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

class Counter {
    private static int totalCount = 0;  // shared across all instances
    private int instanceId;              // unique per instance

    Counter() {
        totalCount++;
        instanceId = totalCount;
    }

    static int getTotalCount() { return totalCount; }
    int getInstanceId()        { return instanceId; }
}

Counter c1 = new Counter();
Counter c2 = new Counter();
Counter c3 = new Counter();

System.out.println(Counter.getTotalCount()); // 3
System.out.println(c1.getInstanceId());       // 1
System.out.println(c3.getInstanceId());       // 3

ค่าคงที่ด้วย static final

ประกาศค่าคงที่เป็น public static final ตามธรรมเนียมแล้วจะตั้งชื่อด้วยรูปแบบ SCREAMING_SNAKE_CASE

class MathConstants {
    public static final double PI      = 3.141592653589793;
    public static final double E       = 2.718281828459045;
    public static final double GOLDEN  = 1.618033988749895;
    public static final int    PRIMES[] = {2, 3, 5, 7, 11, 13};
}

// Access without an instance
System.out.println(MathConstants.PI);

// Constants on domain classes
class HttpStatus {
    public static final int OK        = 200;
    public static final int NOT_FOUND = 404;
    public static final int SERVER_ERR = 500;
}

บล็อกตัวเริ่มต้นแบบสแตติก

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

import java.util.*;

class Config {
    public static final Map<String, String> DEFAULTS;

    static {
        Map<String, String> map = new HashMap<>();
        map.put("timeout",  "30");
        map.put("maxRetry", "3");
        map.put("logLevel", "INFO");
        DEFAULTS = Collections.unmodifiableMap(map);
    }
}

System.out.println(Config.DEFAULTS.get("timeout")); // 30

รูปแบบตัวนับแบบสแตติก

มักใช้ฟิลด์สแตติกสำหรับสร้าง ID นับตัวชี้วัด หรือเก็บแคชที่ใช้ร่วมกัน

import java.util.concurrent.atomic.AtomicLong;

class Order {
    private static final AtomicLong ID_SEQUENCE = new AtomicLong(1000);

    private final long id;
    private final String item;

    Order(String item) {
        this.id   = ID_SEQUENCE.getAndIncrement();
        this.item = item;
    }

    long getId()   { return id; }
    String getItem() { return item; }
}

Order o1 = new Order("Laptop");
Order o2 = new Order("Mouse");
System.out.println(o1.getId()); // 1000
System.out.println(o2.getId()); // 1001

ซิงเกิลตันผ่านฟิลด์สแตติก

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

class DatabasePool {
    private static volatile DatabasePool instance;
    private final int maxConnections;

    private DatabasePool() { this.maxConnections = 20; }

    public static DatabasePool getInstance() {
        if (instance == null) {
            synchronized (DatabasePool.class) {
                if (instance == null)
                    instance = new DatabasePool();
            }
        }
        return instance;
    }

    public int getMaxConnections() { return maxConnections; }
}

System.out.println(DatabasePool.getInstance().getMaxConnections()); // 20

การนำเข้าแบบสแตติก

import static ช่วยให้คุณใช้สมาชิกแบบสแตติกได้โดยไม่ต้องใส่คำนำหน้าชื่อคลาส — มีประโยชน์สำหรับค่าคงที่และเมธอดอรรถประโยชน์

import static java.lang.Math.PI;
import static java.lang.Math.sqrt;
import static java.lang.Math.pow;

// Without import static: Math.PI * Math.pow(r, 2)
double radius = 5.0;
double area = PI * pow(radius, 2);
System.out.printf("Area: %.2f%n", area); // 78.54

// Caution: overuse of static imports hurts readability
// Acceptable for: Math.*, Assert.* in tests, TimeUnit

ความปลอดภัยต่อเธรดของฟิลด์สแตติก

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

import java.util.concurrent.atomic.*;

class RequestMetrics {
    private static final AtomicLong requestCount  = new AtomicLong(0);
    private static final AtomicLong totalLatencyMs = new AtomicLong(0);

    public static void record(long latencyMs) {
        requestCount.incrementAndGet();
        totalLatencyMs.addAndGet(latencyMs);
    }

    public static double averageLatency() {
        long count = requestCount.get();
        return count == 0 ? 0 : (double) totalLatencyMs.get() / count;
    }
}
RequestMetrics.record(45);
RequestMetrics.record(120);
System.out.println(RequestMetrics.averageLatency()); // 82.5

ฟิลด์สแตติกที่เปลี่ยนแปลงได้: ข้อควรระวัง

ฟิลด์สแตติกที่เปลี่ยนแปลงได้เป็นอันตราย: สถานะส่วนกลางที่เปลี่ยนแปลงได้ทดสอบได้ยาก ไม่ปลอดภัยต่อเธรดหากไม่ดูแลอย่างเหมาะสม และสร้างการเชื่อมโยงแฝงระหว่างคลาส

// BAD: mutable static state
class GlobalConfig {
    public static String environment = "dev"; // mutable global!
}
// Any code anywhere can change GlobalConfig.environment
// Very hard to test, unexpected interactions

// BETTER: immutable constant
class GlobalConfig2 {
    public static final String ENVIRONMENT =
        System.getenv().getOrDefault("APP_ENV", "dev");
}

// BEST: inject via constructor (dependency injection)
class Service {
    private final String environment;
    Service(String environment) { this.environment = environment; }
}

รูปแบบต่อต้านการใช้ interface เป็นที่เก็บค่าคงที่

ไม่แนะนำให้ใช้อินเทอร์เฟซเป็นที่เก็บค่าคงที่ (รูปแบบต่อต้านที่เรียกว่า "อินเทอร์เฟซค่าคงที่") ให้ใช้คลาสที่มีคอนสตรักเตอร์เป็น private แทน

// BAD: constant interface — pollutes the namespace of implementing classes
interface FinancialConstants {
    double TAX_RATE = 0.08;  // implicitly public static final
}

// GOOD: utility class for constants
final class FinancialConstants2 {
    private FinancialConstants2() {} // prevent instantiation

    public static final double TAX_RATE  = 0.08;
    public static final double VAT_RATE  = 0.20;
    public static final int    MAX_ITEMS = 100;
}
System.out.println(FinancialConstants2.TAX_RATE); // 0.08

ภาคปฏิบัติ: แฟล็กฟีเจอร์ผ่านค่าคงที่

การใช้ค่าคงที่บูลีนแบบ static final เป็นแฟล็กฟีเจอร์ในเวลาคอมไพล์ — คอมไพเลอร์ JIT จะกำจัดแขนงคำสั่งที่ไม่มีวันทำงาน

class Features {
    public static final boolean ENABLE_ANALYTICS   = true;
    public static final boolean ENABLE_AI_SEARCH    = false;
    public static final boolean DEBUG_MODE          =
        "true".equals(System.getenv("DEBUG"));
}

// The JIT eliminates this if-block when ENABLE_AI_SEARCH is false:
if (Features.ENABLE_AI_SEARCH) {
    System.out.println("Running AI search...");
}

if (Features.DEBUG_MODE) {
    System.out.println("[DEBUG] Request received");
}

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

ฟิลด์สแตติกแตกต่างจากฟิลด์อินสแตนซ์อย่างไร

สรุป: ฟิลด์สแตติกและค่าคงที่

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

  • ฟิลด์สแตติกเป็นของคลาส — มีสำเนาเดียวที่อินสแตนซ์ทั้งหมดใช้ร่วมกัน
  • ค่าคงที่: public static final UPPER_SNAKE_CASE
  • ใช้บล็อกตัวเริ่มต้นแบบสแตติกสำหรับค่าคงที่ที่ต้องเริ่มต้นอย่างซับซ้อน
  • เลือกใช้ AtomicLong/AtomicInteger สำหรับฟิลด์สแตติกที่เปลี่ยนแปลงได้ในโค้ดที่ทำงานพร้อมกัน
  • หลีกเลี่ยงฟิลด์สแตติกที่เปลี่ยนแปลงได้ — ฟิลด์เหล่านี้สร้างสถานะส่วนกลางแฝงที่ทดสอบได้ยาก
  • ใช้คลาสที่สร้างอินสแตนซ์ไม่ได้ (มีคอนสตรักเตอร์เป็น private) สำหรับค่าคงที่แทนการใช้อินเทอร์เฟซ

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

บทเรียน “ฟิลด์แบบ Static และค่าคงที่” ฟรีหรือไม่

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

คุณจะเรียนรู้อะไรในบทเรียน “ฟิลด์แบบ Static และค่าคงที่”

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

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

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

บทเรียน “ฟิลด์แบบ Static และค่าคงที่” ใช้เวลานานแค่ไหน

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

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

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

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

  1. กฎการโอเวอร์โหลดเมธอด
  2. พารามิเตอร์ Varargs
  3. ฟิลด์แบบ Static และค่าคงที่
  4. คลาสอรรถประโยชน์และเมธอดโรงงานแบบ Static
← กลับไปที่ Java Academy