JavaRush /Курсы /Java Syntax Pro /Статические классы (static class) в Java

Статические классы (static class) в Java

Java Syntax Pro
11 уровень , 3 лекция
Открыта

1. Внутренние классы

Недавно вы узнали, что бывают статические переменные и статические методы, но, оказывается, бывают еще и статические классы. Но начнем немного издалека.

В языке Java вполне можно объявлять классы внутри классов. И даже классы внутри классов, которые внутри классов внутри классов. Выглядит это все очень просто:

class ВнешнийКласс
{
   переменные класса
   методы класса 
   class ВнутреннийКласс
   {
      переменные класса
      методы класса
   }
}

Просто объявляем один класс внутри другого — и все.

Пример:

public class Solution
{
   static ArrayList<Point> points = new ArrayList<Point>();

   public static void main(String[] args)
   {
      Point point = new Point();
      point.x = 100;
      point.y = 200;
      points.add(point);
   }

   static class Point
   {
      int x;
      int y;
   }
}

Внутренние классы бывают статические и нестатические. Статические классы еще называют вложенными (static nested class), нестатические просто называют внутренними классами (inner class).



2. Статические классы

Статические вложенные классы можно использовать вне своего родительского класса. Если у такого класса стоит модификатор доступа public, его можно использовать в любом месте программы. Такие классы фактически ничем не отличаются от любого обычного класса. Хотя есть пара отличий.

Имя класса

Если вы хотите обратиться к статическому вложенному классу не из его класса-родителя, а из другого места в программе, вам нужно будет указать имя класса: оно состоит из имени класса родителя и имени вложенного класса. Общий вид этого имени такой:

КлассРодитель.ВложенныйКласс

Примеры:

Класс родитель Вложенный класс Полное имя вложенного класса
com.javarush.Solution
Point
com.javarush.Solution.Point
java.util.Map
Entry
java.util.Map.Entry
java.util.Files
DirectoryStream
java.util.Files.DirectoryStream
java.nio.WindowsPath
Closeable
java.nio.WindowsPath.Closeable

Если вложенный класс имеет свой вложенный класс, их имена просто склеиваются через точку.

Типичный пример вложенного класса в JDK — это класс Entry внутри класса Map. Если вы хотите получить множество пар элементов из объекта HashMap, то метод entrySet() вернет вам множество пар типа Set<Map.Entry>.

Вот запись Map.Entry — это и есть внешний и внутренний классы.

Создание объекта

Создать объект вложенного статического класса очень легко. Выглядит это так:

КлассРодитель.ВложенныйКласс имя = new КлассРодитель.ВложенныйКласс();

Все, как и с обычными классами, только имя двойное.

Обращение к статическим методам

Если у статического класса есть статические методы, обращаться к ним можно точно так же, как к статическим методам обычных классов (только имя класса теперь двойное).

КлассРодитель.ВложенныйКласс.статическийМетод();

Обращение к статическим переменным

Обращаться к публичным статическим переменным вложенного класса тоже легко:

КлассРодитель.ВложенныйКласс.имяСтатическойПеременной


3. Особенности статических классов

Статические внутренние классы меньше всего стоило бы называть статическими. Они ведут себя точно так же, как обычные классы. Никаких ограничений на обращение к ним из нестатических методов нет.

Если вы работаете с внутренним статическим классом внутри его класса-родителя, вообще не заметите никакой разницы с тем, если бы этот внутренний класс был бы самым обычным классом (не вложенным и не статическим).

Пример:

Внутренний статический класс Point Обычный класс Point
public class Solution
{
   static ArrayList<Point> points;

   public static void main(String[] args)
   {
      Point point = new Point();
      point.x = 100;
      point.y = 200;
      points = new ArrayList<Point>();
      points.add(point);
   }

   static class Point
   {
      int x;
      int y;
   }
}
public class Solution
{
   static ArrayList<Point> points;

   public static void main(String[] args)
   {
      Point point = new Point();
      point.x = 100;
      point.y = 200;
      points = new ArrayList<Point>();
      points.add(point);
   }
}

class Point
{
   int x;
   int y;
}

Если вы возьмете какой-то вложенный статический класс и вынесете его из его класса родителя, все, что изменится, так это то, что новый класс потеряет способность обращаться к private static переменным и методам бывшего класса-родителя.

Пример:

Внутренний статический класс Point Обычный класс Point
public class Solution
{    private static ArrayList<Point> points;

   static class Point
   {
      int x;
      int y;

      public static void main(String[] args)
      {
         Point point = new Point();
         point.x = 100;
         point.y = 200;

         // будет работать
         points = new ArrayList<Point>();
         points.add(point);
      }
   }
}
public class Solution
{
   private static ArrayList<Point> points;
}

class Point
{
   int x;
   int y;

   public static void main(String[] args)
   {
      Point point = new Point();
      point.x = 100;
      point.y = 200;

      // тут будет ошибка
      points = new ArrayList<Point>();
      points.add(point);
   }
}

Метод main в обычном классе Point не может обращаться к private static переменной points класса Solution!

Это, собственно, и есть главное отличие вложенного статического класса от обычного класса. Методы вложенного статического класса имеют доступ ко всем статическим переменным и методам своего класса родителя, даже если те объявлены private.

Ну а если разобраться, что тут удивительного? Модификатор private прямо говорит, что к переменным и методам, обозначенным этим модификатором, можно обращаться только изнутри их класса. Внутренний статический класс находится внутри класса-родителя? Да, тогда никаких проблем: обращайтесь сколько хотите.


Комментарии (505)
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
Grigoryvvv Уровень 14 Expert
27 декабря 2025
27.12.2025 / 12 уровень Лекции: В Java не бывает внешних статических классов! Внешние классы всегда обычные. Почему? Ключевое слово static означает принадлежность классу, а не объекту. Но так как внешний класс и так не принадлежит никакому другому классу и значит не может принадлежать объекту другого класса, то и static для него не имеет смысла. Класс static можно использовать только внутри другого класса! Обычные классы могут быть как внешними, так и внутри другого класса. Задачи: • Имеем Внешний класс Outer и Внутренний обычный класс Inner

Outer.Inner inner = new Outer().new Inner(); 
Для создания объекта внутреннего класса нужно создать сначала объект внешнего класса. • Имеем Внешний класс Outer и Вложенный статический класс Nested

Outer.Nested nested = new Outer.Nested();
Для создания объекта вложенного статического класса не нужно создать объект внешнего класса, т.к. он не зависит от объекта внешнего класса. Создаем один объект вложенного класса Nested. В указанном выше коде оператор new создает объект класса Nested обращаясь к конструктору Nested(). Между оператором new и конструктором Nested() нам пришлось вставить слово Outer для указания полного пути к конструктору Nested. Получилось new Outer.Nested(); Во вложенном статической классе мы также можем создать несколько объектов класса Nested:

Outer.Nested nested1 = new Outer.Nested();
Outer.Nested nested2 = new Outer.Nested();
Outer.Nested nested3 = new Outer.Nested();
Коротко: смысл static-вложенного класса не в количестве объектов, а в отсутствии связи с объектом внешнего класса! Вложенный static-класс имеет доступ ТОЛЬКО к static-членам внешнего класса (переменные, методы), даже если они private и ничего не знает об объектах внешнего класса.
Grigoryvvv Уровень 14 Expert
10 января 2026
Статический вложенный класс, это можно сказать тоже самое, что и обычный класс в отдельном файле. Ну и зачем он тогда нужен, спросите вы? Основная польза от статических вложенных классов в отличии от обычных внешних классов: • Логическая группировка классов. Если класс используется только внутри другого класса, логично объявить его вложенным. Улучшает читаемость кода, все находиться в одном месте, а не разбросано во внешних файлах. • Область видимости и инкапсуляция. Статический вложенный класс имеет доступ к private static членам внешнего класса. Класс в отдельном файле — не имеет. • Уровни доступа. Вложенный static класс может быть private (быть видимым только внешнему классу) или protected. Отдельный же класс не может быть private или protected, максимум public и package-private.
C0N5P1RACY Уровень 21
15 декабря 2025
В какой то момент теория в лекциях повернула в какую то сторону, и лекции перестали быть понятны, и как я вижу, многим. В начале курса очень подробно и понятно были изложены многие вещи, из чего все было ясно, сейчас, начиная наверно с уровня так 10го, как будто курс резко поменял автора, ощущение что в начале писал один человек, потом другой, и вот этот "другой" объясняет вообще не понятно. Я не говорю что курс плохой, просто нужно уметь по нему "идти дальше", он хорошо задает направление, и заставляет искать информацию извне. Теперь, совет, как лично Я прохожу этот курс, и мне становится все понятно (может кому то поможет). Я открываю новую лекцию -> Читаю ее ПОЛНОСТЬЮ, мне не понятны многие вещи, даже если ВСЯ лекция не понятна -> Захожу в ГПТ, у меня с ним отдельная тема специально под лекции -> Пишу ему что мне не понятно, даже если вся лекция, и кидаю просто всю лекцию (копировать вставить), прошу его объяснить более человечным языком -> Он дает мне ответ, исходя из этого ответа, я еще раз спрашиваю что мне не понятно -> И вот когда я уже полностью понял в чем тут главная мысль, я прошу ГПТ сделать мне конспект - шпаргалку для Obsidian -> Он делает мне конспект, я ЕЩЕ РАЗ читаю всю эту тему, и заношу ее в Обсидиан -> Возвращаюсь к лекции, читаю ее ЕЩЕ РАЗ для закрепления материала, что то (если прям хорошо написано) копирую в конспект из лекции -> Иду дальше по лекциям, а как накопятся задачи, перехожу в режим "решение задач" -> Открываю отдельную тему с гпт, открываю IDE, пытаюсь решить задачу сам, если мне не понятно -> Кидаю задачу ГПТ и прошу его подсказать, но не показывать код, и даже если с подсказками у меня не получается, то уже смотрю готовое решение (чаще всего это надо что бы просто примерно понять алгоритм действий, я не переписываю готовый код, я смотрю, понимаю как это реализовать, и пишу, но это уже на крайний случай) Удачи вам!
Vadim Уровень 16
25 ноября 2025
я уже привык прокручивать статью не читая, иду в комменты по популярности, потом лекции/видео из интернета, книг, спрашиваю уточняю не понятное у ИИ и потом только тут читаю и делаю задачи. А здешний материал уже так ради приличия читаю в оконцове, всё таки деньги уплочены, надо хоть что-то поиметь за них.
C0N5P1RACY Уровень 21
15 декабря 2025
С каждой лекцией я прям чувствую как тебя все больше и больше прям коробит от этой теории 😂
Vivate Уровень 15
9 сентября 2025
Не много не хватало в теории) Объект не статического внутреннего класса не может существовать без экземпляра внешнего класса: Сначала создается экземпляр внешнего класса: new Outer() Затем на этом экземпляре создается внутренний класс: .new Inner() Аналогия: Представьте, что Outer — это автомобиль, а Inner — двигатель. Двигатель не может существовать без автомобиля.
Anton Zorin Уровень 20
27 августа 2025
КлассРодитель.ВложенныйКласс имя = new КлассРодитель.ВложенныйКласс(); - лекция КлассРодитель.ВнутреннийКласс имя = new КлассРодитель.new ВнутреннийКласс(); - задача)
18 августа 2025
Я еще не читал эту лекцию, сразу пошел комментарии смотреть, мне уже страшно...
REK.QA Уровень 4
4 августа 2025
new Outer().new Inner() - самим догадаться надо?
Anonymous #3492314 Уровень 28
21 июля 2025
В этой статье странное объяснение. В начале заводится речь о вложенных (статических) классах и внутренних (нестатических) классах. Но статья рассказывает только о статических классах, при чем обзывая их попутно уже внутренними и, в добавок к этому, сравнение идет с так называемыми обычными (по сути не вложенными и не внутренними классами). По итогу дается задача на создание объектов отдельно для вложенного (статического класса) и внутреннего (нестатического класса). И становится понятна принципиальная разница двух видов внутренних классов только в задаче на создание объекта внутреннего и объекта вложенного классов. Здесь как бы не ментор нужен, а логика объяснения. Вот с этого надо бы начать и в объяснении распилить тему: Outer.Inner inner = new Outer().new Inner(); Outer.Nested nested = new Outer.Nested(); Если я ошибаюсь, извините великодушно, но если нет, то в общем то несложная тема запутана максимально.
Руслан Уровень 48
20 июля 2025
Ух баля темка 🤡
NinaInfinity Уровень 21
18 июля 2025
долго сидела над последней задачей, в итоге полезла в решение, тк в теории .... = new Parent.Class(); а на деле оказалось .... = new Parent().new Class();