Java中'this'的真正含义是什么?

时间:2013-03-24 00:43:07

标签: java this

我查看了Why can't I use the keyword "this" when referring to fields in static methods?

并认为通过引用变量访问静态成员是可以的,但是使用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
}

}

6 个答案:

答案 0 :(得分:3)

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

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

答案 1 :(得分: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是一个静态字段。就像静态方法一样,它属于类本身,不需要解析实例。

答案 2 :(得分:1)

一旦你理解了static的含义,这真的很简单。

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

当您将方法声明为static时,您会说在不指定特定对象作为当前对象的情况下始终会调用该方法。因此,当您使用static方法时,没有“当前”对象......作为一个逻辑结果,您无法使用this,因为它没有任何意义。

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


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

答案 3 :(得分: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;
  }
}

答案 4 :(得分: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所允许。

答案 5 :(得分:0)

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

您无法在static上下文中使用它,因为根据Java中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.

因此,this doStuff方法中的MyClass引用了MyClass的实例doStuff

this中的MyInnerClass未引用MyClass的实例,而是引用其MyInnerClass的{​​{1}}实例。< / p>

doStuff 始终是指使用关键字的对象实例。如果没有实例,就像this方法中的情况一样,则无法使用static关键字。