0

我查看了为什么在引用静态方法中的字段时不能使用关键字“this”?

并认为通过引用变量访问静态成员是可以的,但使用this访问此类成员是不行的。看看下面的代码。

static int month; 

public static void setMonth(int x)
{ 
Date date = new Date();
date.month = x;  //fine, why ?
    this.month = x;  //compiler error, why ?
}

它清楚地表明它this与参考变量不同。如果是这样,那么它到底是什么?我需要理解它的真正含义,this才能理解为什么它不能从静态上下文中访问。

请不要给我指向随机博客或 oracle 教程的链接,这些链接说this不能从静态上下文中使用——我已经知道了。我想超越这一点,了解为什么不能使用它。

链接问题中的代码 -

public class Date
{

static int month; 

public static void setMonth(int x)
{ 
 this.month = x;  //compiler error
}

public static int getMonth()
{
 return month;  //compiles just fine, no error
}

}
4

6 回答 6

3

当您调用非静态方法时,例如 myObject.myMethod(),编译器会添加一个额外的秘密参数,其值为“myObject”,该参数在方法中可用作“this”。

当您调用静态方法时,例如 MyClass.myStaticMethod(),没有对象可以分配秘密参数的值,因此没有额外的秘密参数,因此“this”在静态方法中不能有值。

于 2013-03-24T00:51:59.283 回答
2
public static void setMonth(int x)
{ 
 this.month = x;  //compiler error
}

this指当前对象实例。静态方法中没有这样的东西,因为静态方法与整个类相关联,而不是任何特定实例。

所以你根本不能this在静态方法中使用。

您引用的字段 ( month) 实际上是静态字段而不是实例字段并不重要。你不需要this在这里,但如果你试图访问它,编译器会阻止你。

public static int getMonth()
{
 return month;  //compiles just fine, no error
}

month是一个静态字段。就像静态方法一样,它属于类本身,不需要实例来解析。

于 2013-03-24T00:46:14.887 回答
1

在您的代码中,date.month = x;完全等同于Date.month = x;编译器在编译时所做的事情。你放在左边的东西实际上并不重要。出于这个原因,非常不鼓励通过引用访问静态字段或方法——看起来点左边的东西很重要,但事实并非如此;只有表达式的编译时类型很重要。考虑

(new Date()).month = x;
((Date)null).month = x;
// suppose SubDate is a subclass of Date, with its own static "month" field
((Date)new SubDate()).month = x;

上面所有的事情都做同样的事情。

所以当你说

并认为通过引用变量访问静态成员是可以的

永远不应使用通过引用变量访问静态成员。因为这是一个巨大的错觉,导致了许多误解和错误;并且可能永远不应该在 Java 中被允许。

于 2013-03-24T06:25:18.130 回答
1

这真的很简单,一旦你明白什么static意思。

关键字(以这种this方式使用时)表示“当前对象”。

当您将方法声明为static时,您是说该方法将始终被调用,而不指定特定对象作为当前对象。所以,当你在一个static方法中时,没有“当前”对象......作为逻辑结果你不能使用this,因为它没有意义。

如果您在实例方法或构造函数中,则只有一个“当前”对象1。在前一种情况下,“当前”对象是您调用该方法的对象。在后一种情况下,它是您正在创建的对象。


1 ...或实例初始化程序块

于 2013-03-24T00:58:44.660 回答
1

为了完整起见,this确实可以用来引用静态字段,前提是它是在非静态代码中完成的,因此this存在。它只是不能在this不存在的地方完成。

public class Test {
  static int month;
  public static void main(String[] args) {
    new Test().setMonth(5);
    System.out.println(month);
  }
  public void setMonth(int x)
  { 
      this.month = x;
  }
}
于 2013-03-24T01:10:55.957 回答
0

关键字this引用当前对象实例。

您不能从上下文中使用它,因为在 javastatic中没有定义 of 概念的实例。所有实例都可以访问static一个方法。static

一个例子

public static final class MyClass {

    public static final class MyInnerClass {

        public void doStuff() {
            System.out.println(this.toString());
        }

        @Override
        public String toString() {
            return "MyInnerClass toString.";
        }
    }

    public void doStuff() {
        System.out.println(this.toString());
        new MyInnerClass().doStuff();
    }

    @Override
    public String toString() {
        return "MyClass toString.";
    }
}

public static void main(String[] args) throws InterruptedException {
    new MyClass().doStuff();
}

输出

MyClass toString.
MyInnerClass toString.

所以thisindoStuff方法中的 inMyClass指的是MyClassfrom insidedoStuff被调用的实例。

thisinMyInnerClass不是指调用它的实例,而是MyClass指调用MyInnerClass它的实例doStuff

this 总是指在其中使用关键字的对象的实例。如果没有实例,如方法中的情况staticthis则不能使用关键字。

于 2013-03-24T00:50:50.667 回答