JavaRush/Курсы/Java Syntax Pro/Загрузка классов

Загрузка классов

Открыта

Мы уже говорили о том, что классы — это сложные типы данных. А теперь немного поговорим о второй стороне классов — обработке класса Java-машиной: в Java все является объектом, даже класс. Класс является объектом. Интересно? Тогда продолжим.

Загрузка класса в память

На самом деле, при загрузке класса в память создаются три специальных «объекта»:

Загрузка класса в память

Краткое описание картинки

Желтый прямоугольник:

Файл с кодом хранится на диске в виде файла с расширением «.class». Он содержит информацию о классе, его полях и методах, а также код методов, скомпилированный в байт-код.

Оранжевый прямоугольник:

Когда Java-машина загружает класс в память, она компилирует его байт-код в машинный код с учетом процессора компьютера и его операционной системы. Доступ к этому машинному коду есть только у Java-машины: у нас как у Java-программистов его нет.

Зеленый прямоугольник:

Java-машина создает некий объект, который содержит все статические переменные и методы класса. Доступ к этому «объекту» у вас есть по имени класса.

Например, когда вы пишете java.lang.Math.PI, вы обращаетесь к статической переменной PI, которая лежит в классе java.lang.Math. Вот этот java.lang.Math и есть наш зеленый прямоугольник. И именно у него внутри хранится статическая переменная PI.

Синий прямоугольник:

Когда Java-машина загружает код класса в память, она создает специальный объект типа java.lang.Class, в котором хранится информация о загруженном классе: его имя, имена методов, имена и типы полей и т.п.

Название «Class» может немного сбивать столку. Логичнее было бы его назвать ClassInfo: этот класс всего лишь хранит некую информацию о загруженном классе.

Получить объект класса можно у любого типа с помощью команды вида:

Class имя = ИмяКласса.class;

Примеры:

Код Примечание
Class a = String.class;
Получаем объект типа Class с информацией о классе String
Class b = Object.class;
Получаем объект типа Class с информацией о классе Object
Class c = Integer.class;
Получаем объект типа Class с информацией о классе Integer
Class d = int.class;
Получаем объект типа Class с информацией о типе int
Class e = void.class;
Получаем объект типа Class с информацией о типе void

Ссылку на объект с описанием класса можно получить и у объекта: для этого у каждого объекта есть метод getClass(), унаследованный от класса Object.

Примеры:

Код Примечание
Class a = "Привет".getClass();
Тот же объект, что и String.class
Class b = Integer.valueOf(0).getClass();
Тот же объект, что и Integer.class
Class c = Boolean.TRUE.getClass();
Тот же объект, что и Boolean.class
Комментарии (250)
  • популярные
  • новые
  • старые
Для того, чтобы оставить комментарий Вы должны авторизоваться
Euraks Backend Developer
27 сентября, 05:13
Еще есть загрузчики классов, но это уже другая история....
German Gribanov
Уровень 25
13 апреля, 17:54
Объяснение на разноцветных прямоугольниках было слишком простым, поэтому добавили бионаноботов... 👍
Timur Salakhov
Уровень 21
28 января, 19:33
28.01.26
Grigoryvvv
Уровень 28
Expert
23 декабря 2025, 15:52
23.12.2025 / 12 уровень. Мне кажется в лекции не достаточно сделан акцент на отдельные элементы. Первоначально мы набираем вручную наш класс Solution с помощью интегрированной среды разработки IntelliJ IDEA в файл Solution.java. Файл Solution.java храниться на диске. Затем мы запускаем программу компилятор по имени javac (Java Compiler) входящей в состав JDK (Java Development Kit) и наш файл Solution.java перекомпилируется в байт-код и сохраняется в файл Solution.class(желтый блок) 🟡 на диске. Это делается командой <javac Solution.java>. Сохраненный файл Solution.class (желтый блок), это реальный файл, хранящийся на диске в файловой системе. Далее мы можем запустить программу, если в классе Solution.class (желтый блок) есть главный метод public static void main(String[] args). Файл Solution.class запускается с помощью программы java которая в свою очередь запускает JVM (Java Virtual Machine). Основная команда запуска выглядит так < java Solution >, указывается имя класса, без .class. JVM сама найдёт файл Solution.class. Программа java и JVM (Java Virtual Machine) также входят в состав JDK (Java Development Kit) • javac → компилирует (.java → .class) • java (JVM) → запускает (.class → выполнение) Далее JVM загружает байт-код файла Solution.class в память, проверяет его и последовательно создает 3 объекта: • Сначала создается объект java.lang.Class мета-информация (синий блок);🔵 • Далее создается объект Класс Solution, который содержит все статические переменные и методы класса (зеленый блок);🟢 • Далее создается объект Код методов класса Solution скомпилированный в машинном коде(оранжевый блок).🟠 Созданные объекты синего, зелёного и оранжевого блоков хранятся в памяти JVM, а не в отдельных файлах. Solution.java ↓ javac Solution.class 🟡 (файл на диске) ↓ java JVM → main() → выполнение программы → объекты 🔵🟢🟠 в памяти JVM
Grigoryvvv
Уровень 28
Expert
23 декабря 2025, 15:56
Основные ветви стандартной библиотеки классов выглядят так (а всего там тысячи классов): Object ├─ String ├─ Number │ ├─ Integer │ ├─ Long │ ├─ Double │ └─ ... ├─ Throwable │ ├─ Exception │ │ ├─ RuntimeException │ │ └─ ... │ └─ Error ├─ Enum ├─ Class // вот этот класс нас интересует └─ ... Класс java.lang.Class — это служебный класс JVM, который представляет (описывает) любой загруженный класс или интерфейс, у него модификатор final и от него нельзя наследоваться. • Class — это как-бы объект-паспорт класса • Он описывает классы • JVM работает с классами через объекты Class Когда Java-машина загружает байт-код файла Solution.class 🟡 в память, первым делом она создает специальный объект типа java.lang.Class 🔵(синий блок) для конкретного класса (в нашем примере — Solution). То есть она создаёт объект класса Class (экземпляр класса java.lang.Class) описывающий класс Solution. Данный объект класса Class (java.lang.Class 🔵) хранит мета-информацию о классе Solution: - имя класса - информацию о методах и полях - константы - модификаторы У класса Class есть внутри методы — это методы для работы с описанием класса, а не с его логикой. Важно: - он не хранит всё напрямую, - он хранит ссылки на структуры JVM. Единственный «настоящий объект» из 3 созданных блоков 🔵🟢🟠 только синий 🔵. Он является объектом класса Class (java.lang.Class). И этот экземпляр объекта Class описывающего переданный в него любой класс можно получить, например присвоив его переменной типа Class с помощью команды вида:
Class имя = ИмяКласса.class;
Пример: Class a = String.class; Получаем объект типа Class с информацией о классе String Class c = Integer.class; Получаем объект типа Class с информацией о классе Integer
Grigoryvvv
Уровень 28
Expert
23 декабря 2025, 19:36
А можно ссылку на объект с описанием класса получить и у любого объекта, с помощью метода getClass(), для этого у каждого объекта есть метод getClass(), унаследованный от класса Object. Пример:
Class a = "Привет".getClass();    //  идентично Class a = String.class;
Получаем объект типа Class с информацией о классе String. Ну и где нам может пригодиться возможность получения доступа к экземпляру объекта Class описывающий какой-либо класс, спросите Вы? Вы наверное помните, когда нам нужно было переопределить метод equals() в созданном нами объекте, для сравнения нам нужно было точно узнать являются ли два сравниваемых объекта одного класса. Материал 11 уровень, 5 лекция "Сравнение объектов". Внутри написанного нами метода aquals(), для того что бы понять относятся объекты к одному классу или нет, мы используем метод instanceof или getClass(). Отличное применение! Также можно воспользоваться методами класса Class и вывести полное имя класса с пакетом и без пакета:
Class a = "Привет".getClass();
System.out.println(a.getName());  //getName() возвращает полное имя
                                  //класса вместе с пакетом.
System.out.println(a.getSimpleName()); //getSimpleName() возвращает полное
                                    //имя класса без пакета.
Вывод в консоль: java.lang.String String Более сложное применение доступа к классу Class пока рассматривать не будем.
Underdante
Уровень 74
24 февраля, 11:11
т.е. писать вместо instanceof
Class our = String.class ;
String ourClassName = our.getName() ;
Class another = Integer.class ;
String anotherClassName = another.getName() ;

if (ourClassName.equals(anotherClassName)){
    ....
}
длинновато
Grigoryvvv
Уровень 28
Expert
24 февраля, 15:22
Приветствую Вас, Пётр 👋 В моём примере не было сравнения типов — я демонстрировал получение метаданных класса через getClass() и getName(), getSimpleName(). Поэтому обсуждение сравнения здесь не совсем по теме 😁 Обсудим предложенное Вами сравнение. Если вы хотите убедиться, относятся ли объекты строго только к одному классу, то используете getClass(), а если хотите убедиться, относятся ли объекты к одному классу или его подклассу (допускаем наследование и интерфейсы), то используете instanceof:
Underdante
Уровень 74
24 февраля, 16:36
а это в таком случае что ? Вы же написали? . если я чего то не понял прошу объясните пожалуйста.
Вы наверное помните, когда нам нужно было переопределить метод equals()
в созданном нами объекте, для сравнения нам нужно было точно узнать являются
ли два сравниваемых объекта одного класса. Отличное применение!
Grigoryvvv
Уровень 28
Expert
24 февраля, 17:20
Я понял Вас. Спасибо за вопрос 🤝
Сlass our = String.class;
Class another = Integer.class;

if (our == another) {
    System.out.println("our и another одного класса");
} else {
    System.out.println("our и another разных классов");
}
Смотрите. В вашем примере мы не используем getName(), getSimpleName(). Мы даже не создавали никаких объектов. Мы просто смотрим являются ли String и Integer одним классом. Ответ: our и another разных классов. По сути: String и Integer разных классов. Такое себе применение. Я имел ввиду использование метода getClass() отдельно.
public class Solution {
    public static void main(String[] args) {
        String a = "Привет";
        Integer b = 5;

        if (a.getClass() == b.getClass()) {
            System.out.println("a и b одного класса");
        } else {
            System.out.println("a и b разных классов");
        }
    }
}
Вывод: a и b разных классов Как это работает a.getClass() → возвращает объект Class<String> b.getClass() → возвращает объект Class<Integer> == сравнивает объекты Class, то есть проверяет, описывают ли они один и тот же класс В данном случае String и Integer — разные классы, поэтому условие false
Grigoryvvv
Уровень 28
Expert
24 февраля, 17:31
Здесь сравнивается не сами объекты между собой, а только относятся ли объекты к одному классу или нет! Можно применить и метод instanceof, но данный метод допускает наследуемые классы и интерфейсы. То есть в отличие от метода getClass(), в методе instanceof если один объект будет в родительском классе, а другой в наследуемом классе, метод вернёт Try. instanceof и getClass() немножко разные методы, и если с getClass() вы точно уверенны что объекты одного класса, то с instanceof можно наступить на грабли. Главное это знать. В каких то случаях нам нужно получить Try, даже если оба объекта не в одном классе, а в Родительском классе и Наследуемом классе. Смотря что нам надо. А если мы хотим сравнить сами созданные нами объекты между собой, тот тут уже сложнее. Нам надо у этих объектов переопределить наследуемый от класса Object метод aquals() и написать в нём свою реализацию. Исключение конечно же составляют часто используемые объекты Srtring, Integer... Т.к. мы часто их используем, в классах Srtring, Integer метод aquals() уже переписали до нас. Поэтому, если мы сравниваем к примеру строки String, то сразу пишем aquals() и сравниваем их.
Grigoryvvv
Уровень 28
Expert
24 февраля, 17:58
"Вы наверное помните, когда нам нужно было переопределить метод equals() в созданном нами объекте, для сравнения нам нужно было точно узнать являются ли два сравниваемых объекта одного класса. Отличное применение!" Я имел ввиду, что когда мы создаем свои собственные объекты, то для их сравнения между собой нам нужно переопределить метод aquals(). Это материал 11 уровень, 5 лекция "Сравнение объектов". Внутри написанного нами метода aquals(), для того что бы понять относятся объекты к одному классу или нет, мы используем метод instanceof или getClass(). Я поправил текст, что бы было более понятнее 🤝
SUNSHINE
Уровень 30
5 декабря 2025, 23:35
06.12.2025 Grigoryvvv!!! Я жду тебя !;) Пока доплекции прошлого раздела изучу ;)
Grigoryvvv
Уровень 28
Expert
23 декабря 2025, 15:52
Хорошо )
Anonymous #3541949
Уровень 14
8 сентября 2025, 10:53
согласен с остальными комментаторами, не совсем понятно, зачем это нужно. Кто ни будь может объяснить, желательно простым языком, или дать ссылки, на другие ресурсы, с более понятным определением?
invoker main
Уровень 42
16 сентября 2025, 15:37
да всё понятно, просто нужно читать и параллельно задавать вопросы гпт, так понятнее гораздо, он разжевывает материал
Anonymous #3585174
Уровень 33
25 июня 2025, 07:18
like
BigMag2000
Уровень 12
4 января 2025, 12:43
опять нарушена логика курса. метод getClass() объясняется здесь. а использование его в задаче было почему-то в прошлой лекции у кого-то нарушены причинно-следственные связи. то ли у Диего то ли у Амиго то ли у автора-составителя 😊
25 января 2025, 18:15
не душни, учись
Игорь
Уровень 27
10 марта 2025, 07:44
Не учи душнить :)
10 марта 2025, 07:47
будь необучаемым в душниловке)
@itArarat
Уровень 32
20 июля 2025, 12:12
ты будешь это под каждой лекцией писать ?
Anonymous #3525583
Уровень 28
2 января 2025, 10:09
совершенно не понял чем отличается желтый прямоугольник от синего
Юрий Болотин
Уровень 11
23 марта 2025, 10:00
Приветствую! Вам необходимо понять, что желтый прямоугольник (например, DealDTO.class) не эквивалентен синему прямоугольнику (java.lang.Class). Мы уже знаем, что весь исходный код, написанный на Java, сначала компилируется в байт-код с помощью компилятора javac, входящего в состав Java Development Kit. Байт-код сохраняется в специальный class-файл. Т.е., если я создал файл HelloWorld.java, то после компиляции появится файл HelloWorld.class. Хотя class-файл прочитать напрямую человеку будет трудно, в JDK есть инструмент под названием javap, который выводит его содержимое в удобном формате. Пример использования:
javap -verbose HelloWorld.class
Так, появляется желтый прямоугольник, представленный на схеме. Что касается синего прямоугольника (java.lang.Class), представленного на схеме, то он никак не связан с HelloWorld.class, поскольку у него есть свой собственный файл с расширением .class :) Экземпляр (Instance) java.lang.Class используется для представления класса вашего объекта, позволяющего выполнять над ним определенные операции (например, использовать Reflection API). Можете посмотреть байт-код класса java.lang.Class, используя javap:
javap -v java.lang.Class
Надеюсь, что понятно объяснил :)
Yasin Akhmadov
Уровень 1
29 декабря 2024, 12:29
Получается, что при обработке какого-нибудь класса JVM создаёт 3 объекта, чтобы безопасно располагать информацией класса. Сначала создаётся объект, содержащий байт-код программы, то есть всех его методов (доступ к этому объекту имеет только JVM). Затем создаётся второй объект, который содержит все статические переменные и статические методы класса (мы можем к ним обращаться). А уже потом создаётся третий класс, он имеет информацию о названиях переменных и методах, а также о типах всех данных. На диске будет хранится файл с кодом с расширением .class, в нём есть все эти три объекта. Я как-то так понял эту информацию (надеюсь правильно).