Глядя на внутренний код System.out.println, хотите понять, как он работает?

Я только что скачал исходный код jdk и меня заинтересовала функция System.out.println

Посмотрев на класс System в java.lang, я перейду к следующей части:

public final class System {
     public final static PrintStream out = null;

а в java.io класс PrintStream объявлен так:

public class PrintStream extends FilterOutputStream
implements Appendable, Closeable {
     public void println() {

поэтому, если мы вызовем функцию в основной функции System.out.println ()

как это может случиться, если объект out имеет значение null. Почему нет исключения java.lang.NullPointerException. Более того, класс PrintStream не является статическим, чтобы предотвратить создание экземпляра объекта.

Я действительно новичок в java, поэтому, пожалуйста, расскажите мне о деталях, которые мне здесь не хватает

Спасибо,

class PrintStream is not static to prevent the instantiation of the object. В Java нет этой концепции статических классов. Почему вы хотите предотвратить создание экземпляра PrintStream?
Thomas Jungblut 16.09.2018 14:30

объявив Printstream как статический в классе System, это означает, что нет объекта Printstream, который будет создан, хорошо, вы правы, но как насчет функции println, она не статична?

Patrick Schmidt 16.09.2018 14:32
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
4
2
80
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Класс System имеет статический блок, который вызывает метод registerNatives, который является родной метод. В исходном коде есть следующий комментарий:

VM will invoke the initializeSystemClass method to complete the initialization for this class separated from clinit. Note that to use properties set by the VM, see the constraints described in the initializeSystemClass method.

Поэтому, когда registerNatives вызывается из статического блока, метод initializeSystemClass, упомянутый в приведенном выше комментарии, вызывается JVM. Этот метод имеет инициализацию для поля out.

Статический блок вызывается во время загрузки класса. Таким образом, вы можете быть уверены, что всякий раз, когда вы вызываете System.out.println из своего кода, этот статический блок уже был вызван и поле out уже инициализировано.

хорошо, исходя из вашего комментария, out не равен нулю, хорошо, теперь часть вызова нестатического метода, который является println?

Patrick Schmidt 16.09.2018 14:42

Что ж, у System есть статическое поле типа PrintStream. Чтобы получить к нему доступ, вы звоните System.out. Но PrintStream по-прежнему является обычным Java-классом, который может иметь нестатические методы. Итак, как только вы получили объект PrintStream, вызвав System.out, вы можете просто вызвать любой из его нестатических методов как System.out.println().

curlyBraces 16.09.2018 14:45

Спасибо CurlyBraces, это все объясняет. Я думал, что его можно вызвать только в том случае, если метод объявлен как статический, но это может произойти напрямую с помощью объявления статического класса.

Patrick Schmidt 16.09.2018 14:48

Другие вопросы по теме