ฟิลด์แบบ 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 ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- กฎการโอเวอร์โหลดเมธอด
- พารามิเตอร์ Varargs
- ฟิลด์แบบ Static และค่าคงที่
- คลาสอรรถประโยชน์และเมธอดโรงงานแบบ Static