我查看了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
}
}
答案 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
关键字。