Статические вложенные классы
Определяйте статические вложенные классы как связанные вспомогательные типы без ссылки на экземпляр внешнего класса.
«Статические вложенные классы» — бесплатный урок Java Academy на CoddyKit. Это урок 1 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 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Статический вложенный и внутренний классы
Ключевое различие: статические вложенные классы NOT имеют неявной ссылки на экземпляр внешнего класса. Внутренние (нестатические) классы DO имеют такую ссылку.
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.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 — хорошо известный статический вложенный интерфейс
- Отдавайте предпочтение статическому вложенному классу, если ему не нужен доступ к экземпляру внешнего класса
Часто задаваемые вопросы
Урок «Статические вложенные классы» бесплатный?
Да — полный текст урока «Статические вложенные классы» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Java Academy, подпишись на CoddyKit PRO. Курс Java Academy содержит 4 уроков всего.
Чему я научусь в уроке «Статические вложенные классы»?
Определяйте статические вложенные классы как связанные вспомогательные типы без ссылки на экземпляр внешнего класса. Ты практикуешь Java Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Java Academy?
Предыдущий опыт не требуется. Java Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 1 из 4.
Сколько времени занимает урок «Статические вложенные классы»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Java Academy?
Да. Каждый урок Java Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Статические вложенные классы
- Внутренние классы и доступ к внешнему классу
- Локальные и анонимные классы
- Выбор подходящей стратегии вложенности