静态方法中的实例变量

3

我正在准备 Java SE 7 的 OCA 认证,第一章节是关于 Java 基础,其中提到了静态方法:

静态方法与对象无关,不能使用类的任何实例变量。

在下面的示例中,编译器给我报错:

class MyClass2 {

    String a;

    public MyClass2() {

    }

    static void check(){
        if (a.equals("TEST"))
            return; 
    }
}

无法将静态引用转换为非静态字段 a。

如果我这样更改类定义:

class MyClass {

    String a;

    public MyClass() {
        // TODO Auto-generated constructor stub
        check(a);
    }

    static void check(String a){
            if (a.equals("TEST"))
                return; 
    }
}

一切都运行正常,编译器没有显示任何错误,这很奇怪,因为a始终是一个实例变量。


6
a.equals("TEST") 使用方法参数 a,而不是实例字段(具有相同变量名)。构造函数可能会将实例字段传递给方法调用,但对于引用的段落而言这并不重要。 - Tom
在这本书的第53页,我相信你所提到的作者Mala Gupta说过:“静态方法和静态变量都不能访问一个类的非静态变量和方法。但反之亦然:非静态变量和方法可以访问静态变量和方法,因为一个类的静态成员即使没有实例也存在。” - esme_louise
4个回答

2
在第二个例子中,你的 check 函数有一个名为 a 的参数。等式检查是针对它执行的,而不是实例成员 a,后者在 static 上下文中仍然无法访问。

那就不是真的了,静态方法与对象无关,不能使用类的任何实例变量。 - Skizzo

1

静态方法只能引用静态变量。由于非静态变量不属于类,而是属于实例化的特定对象...因此,静态方法无法知道要显示哪个变量。例如,您创建了两个MyClass的实例。

MyClass x,y;
x.a =10;
x.b=20;

那么,从静态函数中选择正确的一个是没有办法知道的,因为静态函数与任何特定实例(x或y)都没有关联。

因此,如果您想访问变量a,则需要将其声明为静态变量。

static String a;

但是,在你的第二个案例中,你有一个作为参数,因此由于参数被引用来代替类级别变量,所以没有错误。如果想要出现错误,请使用this.a来引用类级别变量。

0

在第一种情况下,编译时发生错误 -

  • 您有一个非静态字段String a
  • 您正在尝试从静态方法check()中访问String a

这就是为什么会出现编译错误的原因

而在第二种情况下,没有发生编译错误 -

  • 您正在从构造函数MyClass()中调用静态方法check()
  • 完全可以在不创建类的实例/对象的情况下调用类的静态方法。
    这就是为什么您没有收到任何编译错误的原因。

希望这能帮助您。
非常感谢。


好的,我同意在不创建类的实例/对象的情况下调用静态方法是完全有效的,但问题在于在这个方法中,我正在传递一个指向静态对象的对象引用,这是我的主要关注点。 - Skizzo

0
当您将实例变量传递给静态方法(或任何其他方法)时,您传递的是该变量的值,而不是变量本身。这可能就是为什么您没有出现错误的原因。然而,变量本身并不会变得可用。

在上面的程序中,当您调用带有实例变量参数的check(a)时,但实际上,假设a="xyz",并且当调用check()方法时,该值将被复制到所调用方法'a'的本地变量中,这与实际变量{实例变量}不同,因此您不会遇到任何问题。以上我们已经有了解释这个概念的代码。 - Deepak Dhaka

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接