Я только что скачал исходный код 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, поэтому, пожалуйста, расскажите мне о деталях, которые мне здесь не хватает
Спасибо,
объявив Printstream как статический в классе System, это означает, что нет объекта Printstream, который будет создан, хорошо, вы правы, но как насчет функции println, она не статична?




Класс 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?
Что ж, у System есть статическое поле типа PrintStream. Чтобы получить к нему доступ, вы звоните System.out. Но PrintStream по-прежнему является обычным Java-классом, который может иметь нестатические методы. Итак, как только вы получили объект PrintStream, вызвав System.out, вы можете просто вызвать любой из его нестатических методов как System.out.println().
Спасибо CurlyBraces, это все объясняет. Я думал, что его можно вызвать только в том случае, если метод объявлен как статический, но это может произойти напрямую с помощью объявления статического класса.
class PrintStream is not static to prevent the instantiation of the object.В Java нет этой концепции статических классов. Почему вы хотите предотвратить создание экземпляраPrintStream?