看起来像一个非常基本的查询,但我在思考下面的静态方法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");
}
}
以上代码实际打印 - > 构造函数在此处打印
或换句话说,从静态方法执行非静态方法的主体?
欢迎任何合理的解释。
答案 0 :(得分:4)
[...]构造函数不是成员。
因此,调用它们没有问题,因为它们没有绑定到您的类的实例。这没有意义 - 因此,你不能做到以下几点:
Thing thing = new Thing();
Thing anotherThing = thing.Thing();
构造函数不方法,因此您无法对它们应用“方法逻辑”。 如果您想了解更多信息,整个实例化过程在JLS中有详细记录。见 12.5。创建新的类实例。
答案 1 :(得分:1)
实际上构造函数被编译到静态方法中,这就是JVM在内部创建类实例的方式。
答案 2 :(得分:1)
您正在执行非静态代码,但您没有在静态上下文中执行此操作。
例如:
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();
}
}
这里,即使您是在静态方法中调用方法,也是通过实例使用它,因此不是在静态上下文中。
答案 3 :(得分:1)
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) {
}
}
答案 4 :(得分:1)
在正式语言级别,您应该阅读
行ConstructorTest cnst = new ConstructorTest("here")
作为class instance creation expression。事实上,这不是对构造函数的调用或任何其他方法。
实例创建执行许多步骤,例如为新对象分配内存,初始化字段,调用构造函数和初始化程序块。有关详细的逐步说明,请参阅JLS §12.5。如上所述,构造函数调用只是实例创建的一部分。
此外,您可能会将构造函数视为类的静态部分。实际上,构造函数声明不是成员(参见JLS §8.8)因此它们不可覆盖(也作为静态方法)。要注意:这只是一半。在构造函数内部时,您已经创建了实例,并且您可以调用其他实例方法和/或访问实例字段。