【问题标题】:How is the Static method(main) able to grab hold of non static method(constructor) and execute it?静态方法(主要)如何能够抓住非静态方法(构造函数)并执行它?
【发布时间】:2014-07-09 11:23:55
【问题描述】:

似乎是一个非常基本的查询,但我在思考下面的静态方法 main() 如何能够使用 new 关键字从中执行非静态方法(显然是构造函数)。虽然我知道 new 还带来了一些其他的东西,但我应该如何说服自己这不是静态和非静态方法不能使用非静态规则的例外和静态上下文?

下面是示例代码:

public class ConstructorTest {

    ConstructorTest(String str)
    {
        System.out.println("Constructor Printing "+str);
    }


    public static void main(String[] args) {
        // TODO Auto-generated method stub
        ConstructorTest cnst=new ConstructorTest("here");
    }

} 

上面的代码实际打印了 --> 构造函数在这里打印

换句话说,从静态方法执行非静态方法的主体?

欢迎任何合理的解释。

【问题讨论】:

    标签: java constructor static non-static


    【解决方案1】:

    Java Tutorial 声明

    [...] 构造函数不是成员。

    因此,调用它们没有问题,因为它们没有绑定到您的类的实例。这没有意义 - 因此,您不能执行以下操作:

    Thing thing = new Thing();
    Thing anotherThing = thing.Thing();
    

    构造函数不是方法,因此您不能对它们应用“方法逻辑”。 如果您想了解更多信息,整个实例化过程在JLS 中有很好的记录。参见12.5。创建新的类实例

    【讨论】:

    • 因此,如果您不是该类的成员,则意味着静态和非静态上下文不适用于构造函数?
    • 不,作为构造函数意味着静态和非静态上下文不适用。如果您阅读 JLS,您会发现,由于它们既不是成员也不是方法,因此上下文的问题是无关紧要的。
    • 是的,我的意思是构造函数。感谢您的澄清。
    【解决方案2】:

    实际上构造函数被编译成静态方法,这就是JVM内部创建类实例的方式。

    【讨论】:

    • 能否提供参考。
    • 我在 Bruce Eckel 的 Thinking in Java 中读到了这一点 - 不幸的是我没有那本书,所以我稍后会尝试提供参考。
    【解决方案3】:

    您正在执行非静态代码,但不是在静态上下文中执行。

    例如:

    public class C1{
    
      private int x;
      public String do(){  System.out.println("x = " + x);}
    
       public static void main(String[] args){
         do();
       }
    
    }
    

    这是行不通的,因为 do 是一个实例方法,它可能运行特定于该实例的代码。那么,VM 如何知道要使用哪个实例,或者 x 应该具有什么值?

    现在,首先使用构造函数,这在任何上下文中都是可能的:

    public class C1{
    
      private int x;
      public String do(){  System.out.println("x = " + x);}
    
       public static void main(String[] args){
         C1 t = new C1();
         t.do();
       }
    
    }
    

    在这里,即使您从静态方法中调用该方法,您也是通过实例使用它,因此不在静态上下文中。

    【讨论】:

    • op 不是在说实例方法,而是在调用构造函数本身。
    • 自从我发布以来,操作员已经编辑了他的问题。第一个问题是:我怎么可以在静态方法中调用非静态构造函数。
    • 我的问题是你怎么能简单地调用 C1() 因为它是一个构造函数并且它是非静态的?
    【解决方案4】:

    ConstructorTest 不是方法。 它是一个构造函数,您可以使用构造函数来初始化类属性。 您也可以像这样从构造函数初始化静态变量:-

    public class XYZ 
    {
    static int i=0;
    
    public XYZ() {
        i=1;//not an compile time error
    }
    
    public static void doSome(){}
    
    public static void main(String[] args) {
    
    }
    
    }
    

    【讨论】:

      【解决方案5】:

      在正式的语言级别上,您应该阅读该行

      ConstructorTest cnst = new ConstructorTest("here")
      

      作为class instance creation expression。事实上,这不是对构造函数的调用或任何其他方法。

      实例创建包含许多步骤,例如为新对象分配内存、初始化字段、调用构造函数和初始化块。有关详细的分步说明,请参阅JLS §12.5。如此说来,构造函数调用只是实例创建的一部分。

      此外,您可能会将构造函数视为类的静态部分。事实上,构造函数声明不是成员(参见JLS §8.8),因此它们是不可覆盖的(静态方法也是如此)。当心:这只是对了一半。在构造函数内部时,您已经创建了实例,并且可以调用其他实例方法和/或访问实例字段。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-02-17
        • 1970-01-01
        • 1970-01-01
        • 2017-12-19
        • 2017-04-30
        • 2011-12-29
        • 2023-03-10
        相关资源
        最近更新 更多