静态方法访问非静态构造函数?

Ahm*_*rim 9 java static constructor ambiguous

我昨天参加了Java考试.有些东西对我来说似乎很模糊.

规则很简单:

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

    public class Main {
        public static void main(String[] args) {
            Main p = new Main();
            k();
        }
    
        protected Main() {
            System.out.print("1234");
        }
    
        protected void k() {
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)
    Main p = new Main() line prints 1234
    k() line raises error
    
    Run Code Online (Sandbox Code Playgroud)

那么为什么会这样呢?它不与上面的Java规则冲突吗?

aio*_*obe 12

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

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

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

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

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

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


所以,总结一下:

Main p = new Main();
Run Code Online (Sandbox Code Playgroud)

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

k();
Run Code Online (Sandbox Code Playgroud)

不合适,因为它等同于(静态)主方法this.k()并且this不可用.


Pét*_*rök 5

在这方面,构造函数不是普通的方法.构造函数的重点是构造一个新的类实例.

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

一些澄清:

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

不完全的.您可以从静态方法中调用非静态方法,只需将其范围限定为该类的特定对象即可.即

p.k();
Run Code Online (Sandbox Code Playgroud)

将在上面的代码示例中完美地工作.

电话

k();
Run Code Online (Sandbox Code Playgroud)

在一个实例(非静态)方法中会很好.它等同于

this.k();
Run Code Online (Sandbox Code Playgroud)

隐含this指的是该类的当前实例.每当编译器k()在实例方法中看到一个非限定调用时,它就会自动将其作为范围this..但是,由于静态方法不依赖于类的任何实例,因此您(和编译器)不能引用this静态方法.因此,您需要显式命名该类的实例以调用实例方法.


Jon*_*eet 5

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

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

Integer x = Integer.valueOf(10);
int y = x.intValue(); // Instance method!
Run Code Online (Sandbox Code Playgroud)

真正的问题是"有没有this一个静态方法中引用".

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

说实话,这不是一个真正有用的模型.它使更多的意义(从查看来电者的角度)考虑构造与返回类型这是一样的声明类的静态方法,但即使这是不以任何方式一个完美的模型.

我建议你把构造函数看作一个不同类型的成员.接受构造函数和方法之间的差异,而不是试图隐藏它们.