11

我的假设

  1. 静态方法不能调用非静态方法。
  2. 构造函数是一种没有返回类型的方法

鉴于这个例子......

    public class Main {
        public static void main(String[] args) {
            Main p = new Main();  // constructor call
            k();  // [implicit] `this` reference
        }

        protected Main() {
            System.out.print("1234");
        }

        protected void k() {
        }
    }
  • 此行打印 1234:Main p = new Main()
  • 此行引发异常:k()

为什么示例代码做了这两件事?它们不与我的上述假设相冲突吗?我的假设是否正确?

4

3 回答 3

11

1 - 静态方法不能调用非静态方法。

当然可以,但是他们需要一个对象来调用.

在静态方法中,没有this可用的引用,因此foo()(相当于this.foo())是非法的。

2 - 构造函数是一种没有返回类型的方法。

如果要将它们与 methods 进行比较,我会说构造函数更接近非静态方法(因为构造函数内部确实存在this引用)。

鉴于这种观点,您应该清楚为什么静态方法可以毫无问题地调用构造函数。


所以,总结一下:

Main p = new Main();

没关系,因为new Main()不依赖于任何现有对象。

k();

不行,因为它等效于您的(静态)主要方法this.k()并且this在您的(静态)主要方法中不可用。

于 2012-05-09T09:49:00.740 回答
6

不。在这方面,构造函数不是普通的方法。构造函数的全部意义在于,构造一个新的类实例。

所以它也可以在静态范围内调用。想一想:如果您需要类的现有实例来创建它的新实例,那么您将永远无法实例化它。

一些澄清:

静态方法不能调用非静态方法。

不完全的。您可以从静态方法内部调用非静态方法,只需要将其范围限定为该类的特定对象。IE

p.k();

将在您上面的代码示例中完美运行。

通话

k();

在实例(非静态)方法中会很好。它相当于

this.k();

隐含this指的是类的当前实例。每当编译器在实例方法中看到不合格的调用k()时,它会自动将其范围使用this.. 但是,由于静态方法不绑定到类的任何实例,您(和编译器)不能this在静态方法内部引用。因此,您需要显式命名类的实例以调用实例方法。

于 2012-05-09T09:49:33.287 回答
5

规则很简单:
1 - 静态方法不能调用非静态方法。

这根本不是真的。静态方法可以调用非静态方法,只需通过“目标”引用。例如,这在静态方法中很好:

Integer x = Integer.valueOf(10);
int y = x.intValue(); // Instance method!

真正的重点是“this静态方法中没有引用”。

2 - 构造函数是一种没有返回类型的方法。

老实说,这不是一个真正有用的模型。(从调用者的角度来看)将构造函数视为具有与声明类相同的返回类型的静态方法更有意义,但无论如何这也不是一个完美的模型。

我建议您将构造函数视为不同类型的成员。拥抱构造函数和方法之间的差异,而不是试图隐藏它们。

于 2012-05-09T09:50:25.143 回答