【问题标题】:Java static reference variable invoking non-static methods调用非静态方法的 Java 静态引用变量
【发布时间】:2019-03-10 07:46:20
【问题描述】:
class A{
    void display(){
      System.out.println("hai");
      }
}
class B {
    static A a;
}
class C{
    public static void main(String args[])
    {
      B.a.display();
      // no compile- time error here.why?
    }
}

我也知道 a 将在运行时设置为 null。但是编译器不应该知道 我们正在访问一个非静态方法 通过静态引用变量? 这在执行时会产生 空指针异常,但为什么编译器没有给出 错误。

这是否意味着静态引用变量的行为与对象引用完全一样,因此可以调用类的任何方法(静态和非静态)?

编辑:我基本上对静态字段的访问规则感到困惑。 根据定义,静态字段只能直接访问其他静态字段。 那么这不包括 "invoking" 使用静态引用变量的方法吗? 并且 display() 在它的对象被创建之前被访问。这有效吗?

【问题讨论】:

  • 我不明白这个问题。如果a 引用了A 的实例,为什么不能调用实例方法?
  • 在单独的课程中,这会起作用(为什么不呢?)。但是当这些类是子类(非静态子类)时,你一开始就不能在非静态类中声明静态变量。我的猜测是这种机制让您感到困惑?
  • 所以静态引用变量可以“调用”任何方法。他们只能直接“访问”非静态对吗?我假设我们不能调用非静态方法,因为变量是静态的。
  • 不,静态变量(引用)可以调用类的任何成员。这只是一个普通的参考,就像任何其他参考一样。所以给我们一个例子,这样我们就可以看到你在说什么。
  • 有几件事您可能会感到困惑。 局部变量必须明确初始化,编译器可以判断它们是否已经初始化,因为它们是本地的。如果您尝试使用尚未初始化的局部变量,您将收到编译器错误。另一种是从静态方法(或其他静态上下文)直接(而不是通过引用)引用实例成员。这些也肯定是错误,编译器会标记它们。

标签: java object reference static static-methods


【解决方案1】:

“你一直用那个词。我不认为它意味着你认为它的意思。”

代码中的static A a; 表示,“a 是(引用)A 类型的对象,在类B 的所有实例之间共享。a 未初始化。”。

编译器将没有上下文来确定您何时调用类C 的静态main() 方法,因此它无法判断变量a 在您调用时的状态C.main();。事实上,你可以很容易地拥有一个 D 类:

class D
{
    public static void main( String args[] )
    {
        B.a = new A();
        C.main( args );
    }
}

这将使上面的代码完全有效和可运行。

【讨论】:

  • 是的,我错误地添加了 extends A。更正了我的问题
猜你喜欢
  • 2015-02-21
  • 1970-01-01
  • 2013-03-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多