0Pricing
Java Academy · Lekcja

Pola statyczne i stałe

Używaj pól statycznych do przechowywania współdzielonego stanu, stałych z static final oraz inicjalizatorów statycznych.

Pola statyczne i stałe to bezpłatna lekcja Java Academy na CoddyKit. To lekcja 3 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Java Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Java Academy zawiera 4 lekcji w sumie.

Pola statyczne i stałe

Pola statyczne należą do klasy, a nie do instancji. Są współdzielone przez wszystkie obiekty tej klasy. Stałe łączą modyfikatory static i final, tworząc niezmienne wartości na poziomie klasy.

Pola statyczne a pola instancji

Każdy obiekt ma osobną kopię pola instancji. Pole statyczne ma jedną kopię współdzieloną przez wszystkie obiekty danej klasy.

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

Stałe z użyciem static final

Deklaruj stałe jako public static final. Zgodnie z konwencją używają one nazewnictwa 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;
}

Bloki inicjalizacyjne static

Gdy stała wymaga złożonej inicjalizacji, użyj bloku inicjalizacyjnego static, który zostanie wykonany raz podczas ładowania klasy.

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

Wzorzec statycznego licznika

Pola statyczne są często używane do generowania identyfikatorów, zliczania wartości metryk lub przechowywania współdzielonych pamięci podręcznych.

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 za pomocą pola statycznego

Pole statyczne przechowuje jedyną instancję Singletona. W przypadku klas, które nie zawsze będą potrzebne, należy użyć leniwej inicjalizacji.

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 statyczny

import static pozwala używać elementów statycznych bez prefiksu z nazwą klasy — jest to przydatne w przypadku stałych i metod narzędziowych.

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

Bezpieczeństwo wątkowe pól statycznych

Pola statyczne współdzielone między wątkami wymagają synchronizacji albo użycia typów atomowych, aby uniknąć wyścigów.

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

Zmienna zawartość pól statycznych: zagrożenia

Zmienne pola statyczne są niebezpieczne: globalny zmienny stan jest trudny do testowania, bez odpowiedniej ostrożności nie jest bezpieczny wątkowo i tworzy ukryte zależności między klasami.

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

Antywzorzec interfejsu stałych

Używanie interfejsu do przechowywania stałych (antywzorzec „Constant Interface”) jest odradzane. Zamiast tego użyj klasy z prywatnym konstruktorem.

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

Praktycznie: przełączniki funkcji za pomocą stałych

Używanie stałych logicznych static final jako przełączników funkcji rozstrzyganych podczas kompilacji — kompilator JIT usuwa martwe gałęzie.

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

Szybki test

Czym różni się pole statyczne od pola instancji?

Podsumowanie: pola statyczne i stałe

Najważniejsze informacje:

  • Pola statyczne należą do klasy — jedna kopia współdzielona przez wszystkie instancje
  • Stałe: public static final UPPER_SNAKE_CASE
  • Używaj bloków inicjalizacyjnych static w przypadku stałych wymagających złożonej inicjalizacji
  • W kodzie współbieżnym preferuj AtomicLong/AtomicInteger dla zmiennych pól statycznych
  • Unikaj zmiennych pól statycznych — tworzą ukryty globalny stan, który trudno testować
  • Zamiast interfejsu używaj klasy, której nie można instancjonować (z prywatnym konstruktorem), do przechowywania stałych

Często zadawane pytania

Czy lekcja „Pola statyczne i stałe” jest bezpłatna?

Tak — pełny tekst „Pola statyczne i stałe” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Java Academy, przejdź na CoddyKit PRO. Kurs Java Academy zawiera 4 lekcji w sumie.

Co nauczysz się w „Pola statyczne i stałe”?

Używaj pól statycznych do przechowywania współdzielonego stanu, stałych z static final oraz inicjalizatorów statycznych. Ćwiczysz Java Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć Java Academy?

Nie wymagamy żadnego doświadczenia. Java Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 3 z 4.

Ile czasu zajmuje lekcja „Pola statyczne i stałe”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji Java Academy?

Tak. Każda lekcja Java Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Zasady przeciążania metod
  2. Parametry varargs
  3. Pola statyczne i stałe
  4. Klasy narzędziowe i statyczne metody fabrykujące
← Powrót do Java Academy