Java Academy · Lektion

Statiske felter og konstanter

Brug statiske felter til delt tilstand, konstanter med static final og statiske initialiseringsblokke.

Lektion 3 af 413 trin

Statiske felter og konstanter er en gratis Java Academy-lektion på CoddyKit. Dette er lektion 3 af 4. Du kan læse hele lektionen gratis nedenfor — og derefter øve dig praktisk i browseren med en indbygget kodeeditor og en AI-vejleder, der er tilgængelig døgnet rundt. Den er en del af læringsforløbet i Java Academy, og dine fremskridt synkroniseres på tværs af nettet og CoddyKit-appen. Java Academy-kurset indeholder 4 lektioner i alt.

Statiske felter og konstanter

Statiske felter tilhører klassen, ikke instanserne. De deles af alle objekter i klassen. Konstanter kombinerer static og final for at oprette uforanderlige værdier på klasseniveau.

Statiske felter kontra instansfelter

Et instansfelt har en separat kopi pr. objekt. Et statisk felt har én kopi, der deles af alle objekter i klassen.

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

Konstanter med static final

Deklarer konstanter som public static final. Efter konvention bruger de 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;
}

Statiske initialiseringsblokke

Når en konstant kræver kompleks initialisering, skal du bruge en statisk initialiseringsblok, der kører én gang, når klassen indlæses.

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

Mønsteret med en statisk tæller

Statiske felter bruges ofte til generering af id'er, optælling af målinger eller delte cacher.

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

Singleton via et statisk felt

Et statisk felt indeholder den ene instans i en Singleton. Brug forsinket initialisering til klasser, der måske ikke altid er nødvendige.

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

Statisk import

import static giver dig mulighed for at bruge statiske medlemmer uden præfikset med klassenavnet — det er nyttigt til konstanter og hjælpeværktøjsmetoder.

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

Trådsikkerhed for statiske felter

Statiske felter, der deles mellem tråde, kræver synkronisering eller atomare typer for at undgå kapløbstilstande.

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

Foranderlige statiske felter: faldgruber

Foranderlige statiske felter er farlige: global foranderlig tilstand er svær at teste, er ikke trådsikker uden omhu og skaber skjult kobling mellem klasser.

// 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; }
}

Anti-mønsteret med en konstantgrænseflade

Det frarådes at bruge en grænseflade til at indeholde konstanter (anti-mønsteret "Constant Interface"). Brug i stedet en klasse med en privat konstruktør.

// 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

Praktisk: Funktionsflag via konstanter

Brug af statiske final boolean-konstanter som funktionsflag på kompileringstidspunktet — JIT-kompileren fjerner døde grene.

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");
}

Hurtigt tjek

Hvad er forskellen på et statisk felt og et instansfelt?

Opsummering: Statiske felter og konstanter

Vigtigste pointer:

  • Statiske felter tilhører klassen — én kopi, der deles af alle instanser
  • Konstanter: public static final UPPER_SNAKE_CASE
  • Brug statiske initialiseringsblokke til konstanter, der kræver kompleks initialisering
  • Foretræk AtomicLong/AtomicInteger til foranderlige statiske felter i samtidig kode
  • Undgå foranderlige statiske felter — de skaber skjult global tilstand, som er svær at teste
  • Brug en klasse, der ikke kan instantieres (privat konstruktør), til konstanter i stedet for en grænseflade
Gratis at komme i gang

Lær Java med en AI-underviser — gratis

Skriv og kør rigtig kode i din browser, få øjeblikkelig hjælp fra en AI-underviser døgnet rundt, og fortsæt, hvor du slap, på web eller i appen.

Kurser
104
Lektioner
374

Ofte stillede spørgsmål

Er lektionen “Statiske felter og konstanter” gratis?

Ja — hele teksten til “Statiske felter og konstanter” kan læses gratis her på nettet. Hvis du vil øve dig interaktivt med en indbygget kodeeditor og en AI-vejleder døgnet rundt og få adgang til resten af Java Academy-kurset, skal du opgradere til CoddyKit PRO. Java Academy-kurset indeholder 4 lektioner i alt.

Hvad lærer jeg i “Statiske felter og konstanter”?

Brug statiske felter til delt tilstand, konstanter med static final og statiske initialiseringsblokke. Du øver dig i Java Academy med praktisk kode, som du kører direkte i browseren, og en AI-vejleder døgnet rundt besvarer dine spørgsmål, mens du arbejder dig gennem lektionen.

Skal jeg have erfaring for at begynde på Java Academy?

Der kræves ingen tidligere erfaring. Java Academy på CoddyKit er tilrettelagt for både begyndere og øvede, så du kan starte her eller fra begyndelsen og lære i dit eget tempo. Dette er lektion 3 af 4.

Hvor lang tid tager lektionen “Statiske felter og konstanter”?

De fleste CoddyKit-lektioner tager cirka 5–10 minutter. Hver lektion er kort og interaktiv, så du gør løbende fremskridt og kan fortsætte, hvor du slap – på både web og app.

Kan jeg skrive og køre kode i denne Java Academy-lektion?

Ja. Alle Java Academy-lektioner har en indbygget kodeeditor, så du kan skrive og køre rigtig kode direkte i din browser og få øjeblikkelig feedback fra AI – uden lokal opsætning.

Alle lektioner i dette kursus

  1. Regler for method overloading
  2. Varargs-parametre
  3. Statiske felter og konstanter
  4. Hjælpeklasser og statiske factory-metoder
← Tilbage til Java Academy