【问题标题】:Why System class doesn’t requires instantiation? [duplicate]为什么 System 类不需要实例化? [复制]
【发布时间】:2020-07-08 06:34:13
【问题描述】:

首先抱歉,如果这是一个非常基本的问题,但有人问我这个问题,我没有任何答案。

在声明中

    System.out.println()

System是java.lang包中的一个类,out是System类的静态变量,println()是一个重载方法。 那为什么 System 类不需要实例化呢?

谢谢

【问题讨论】:

  • 好吧,你的意思是系统是一个不需要实例化的静态类?
  • 否;再次阅读您自己的描述。 out 是 System.系统特殊;它不是static,但它不能被实例化。但是我们不需要实例化它,因为它在类本身中存储了一个名为outPrintStream,而不是在实例中。
  • 如果你看一下 Integer,它有静态和非静态方法。调用非静态方法时需要一个实例。非静态的。 Integer i = 1;然后i.toString() 与静态版本。 Integer.toString(1) 不需要实例。
  • 这能回答你的问题吗? out in System.out.println()

标签: java


【解决方案1】:

java.lang.* 是默认导入的,即你的程序可以访问java.lang.* 包中的所有类。因此,您的类可以访问System 类的成员,其中有out,一个PrintStream 类型的静态字段。静态成员不绑定到类的实例,因此可以直接访问它们而无需实例化。因此,您可以调用out 可用的重载打印方法。

【讨论】:

    【解决方案2】:

    如果在 Java 类中声明静态方法,则无需创建对象,只需调用 System.out.println() 等方法即可。

    【讨论】:

      【解决方案3】:

      无论如何都无法实例化 System 类(参见Javadoc)。

      这是通过将构造函数设置为私有来实现的:

      private System() {
      }
      

      但是,例如 openj9 中的 System 类部分是通过调用 afterClinitInitialization() 方法来填充的,该方法在线程初始化之后调用。

      在那里,out 变量实际上已被初始化:

      setOut(new PrintStream(new BufferedOutputStream(new FileOutputStream(FileDescriptor.out)), true));
      

      见:

      System.afterClinitInitialization()

      Thread.initialize()

      在那之后,它就不再可以通过 Github 进行追踪了,但我想你明白了。初始化只是由 JVM 完成,由于 out 是静态的,因此不需要 System 的实例来访问该变量。

      然而,静态变量的主题已经很好地涵盖了:

      What does the 'static' keyword do in a class?

      Static (Keyword) - Wikipedia.com

      要完全理解这一点,你必须对 JVM 和原生编程有相当的了解,我必须在这方面投降。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-04-05
        • 2018-02-22
        • 2011-04-24
        相关资源
        最近更新 更多