为什么我们不能在静态方法中使用“this”关键字

Why can't we use 'this' keyword in a static method

提问人:Pradeep Vairamani 提问时间:7/26/2012 最后编辑:brimboriumPradeep Vairamani 更新时间:10/31/2023 访问量:98849

问:

class Sub {
    static int y;
    public static void foo() {
         this.y = 10;
    }
}

我知道这表示调用该方法的对象,并且静态方法不绑定到任何对象。但在上述情况下,变量 y 也是静态的。this

如果我们可以在类对象上调用静态方法,为什么我们不能允许静态方法来设置类的静态变量。

这个附加约束的目的是什么?

java oop 静态 这个

评论

0赞 Mark McKenna 2/11/2017
我意识到这是一个古老的问题,但我想把它+1作为一个非常有效的观点。尽管对于字段,答案很简单(省略限定符),但对于静态内部类,它变得相关,并且当您需要对类本身的运行时实例的引用时,它也是相关的。例如,我可以键入“MyClass.class”来获取单例 Class<MyClass>,但只有“class”本身是无效的,并且没有类似的解决方法。这导致类名可能会在单元中重复,而单元不是很 DRY。

答:

2赞 tibtof 7/26/2012 #1

为了让你的代码正常工作,请这样写:

class Sub {
    static int y;
    public static void foo() {
         Sub.y = 10;
    }
}

可以在静态方法中设置静态字段,但无权访问 in static method,因为表示对象的当前实例,而在静态方法中没有实例。thisthis

评论

0赞 tibtof 7/26/2012
你愿意解释一下我的答案或@Peter的答案有什么问题吗?
0赞 brimborium 7/26/2012
你的回答没有错。再次将其投票为 0。(由于蹩脚的投票-代表系统^^,这让你总体上只有 +8 代表)
2赞 Peter Lawrey 7/26/2012 #2

这意味着“这个”对象,但没有一个。在您的情况下,您可以按照@tibtof建议使用类名。

6赞 mrswadge 7/26/2012 #3

this指的是对象的这个实例。正如方法所示,不存在 的实例。SubstaticSub

99赞 brimborium 7/26/2012 #4

因为指的是对象实例。静态方法的调用中没有对象实例。但是,当然,您可以访问静态字段(仅限静态字段!只需使用this

class Sub {
    static int y;
    public static void foo() {
         y = 10;
    }
}

如果要确保获取的是静态字段,而不是具有相同名称的局部变量,请使用类名指定:y

class Sub {
    static int y;
    public static void foo(int y) {
         Sub.y = y;
    }
}

评论

5赞 xehpuk 12/17/2015
反对者可能认为这并不能真正回答问题,因为你基本上重复了 OP 已经知道的内容,只提供了一个冗长的解决方法。如果类被命名,那么在静态方法中引用该类不是更好吗?ThisClassHasAQuiteLongNamethis
0赞 brimborium 12/18/2015
但事实并非如此,我已经解释了为什么不能在静态方法中使用(因为没有要命名的类的实例),并展示了两种访问字段的方法。能够在静态上下文中用作类名的替换将是误导和不一致的(至少恕我直言)。感谢您的反馈,这也可能是投反对票的原因。thisthisthis
4赞 Diogenes Creosote 2/16/2017
正如我所理解的,我也想知道的问题是,为什么 Java 不会在静态上下文中重载 的含义来表示类,因此可以键入 .这似乎是一个显而易见的设计选择,因为它消除了明确提及类名的需要,类名可能会发生变化。一般来说,当有人问“为什么 x 被定义为 y,而不是在不同的上下文中被定义为 z”时,这并不令人满意,而且回答“因为它被定义为 y”确实有点有毒和居高临下。这让我觉得自己很愚蠢,因为我现在仍然在想同样的事情。thisSub.ythis.y
0赞 brimborium 2/20/2017
@AndrewCone感谢您的反馈。你提出了一个非常好的观点(关于为什么我被否决了)。关于这个话题:我认为原因是 Java 专注于拥有(或至少试图拥有)一个干净的面向对象结构。当您使关键字过载时,可读性会受到影响。根据当前定义,当您阅读 时,您知道它是一个局部变量,而不是静态变量。所以它更干净。this.y
0赞 sakthisundar 7/26/2012 #5

关键字“this”是指您正在操作的对象。在你的例子中,这是在任何非静态方法或构造函数中(如果你有一个,并且如果你在里面使用“this”),那么“this”指的是类的那个特定实例,Sub.So 它只在创建对象时适用。但是,在类的静态上下文中,您甚至可以在不为此创建对象的情况下使用,因为它是在类加载期间解析的。“this”仅在创建对象时解析(您甚至可以动态地说出哪个对象)。因此,“this”在静态上下文中是有道理的。希望它有所帮助。上帝保佑。

7赞 Sachindra N. Pandey 6/1/2015 #6

我们不能在静态方法上下文中使用“this”的主要原因是:-

this :- “this” 表示当前类 OBJECT ,所以很明显“this”只进来 一旦我们打算创建该类的 Object,图片。

静态方法:- 无需创建对象即可使用静态方法。 根据 Java 规则,意味着“实例”或对象创建与“静态”没有任何意义。

所以如果我们同时使用两者(静态和这个),就会有矛盾。 这就是我们不能在静态方法中使用“this”的原因。

评论

1赞 Ram 7/5/2018
您刚才提到有一个 Java 规则,即不使用类实例来调用静态字段。没有这样的 Java 规则,而是有一些特定的原因“静态字段/方法仅在编译时调用的内存区域中创建并存储。静态的东西只是类的一部分,所以我们可以直接用类名访问它们,不需要创建实例来访问它们”。PermGen
1赞 Rajat Saxena 3/8/2016 #7

“this” 关键字仅适用于创建对象实例的情况。在静态方法中,不会创建任何实例,因为静态方法属于类区域。

0赞 anjli rajput 5/20/2018 #8

当我们声明变量并且方法是静态的时,这是在对象之间共享的,其中此关键字仅指向当前对象。假设你已经创建了五个类 foo 的对象,那么只有一个 made of (int y) 的副本被所有 object.so 切碎,如果你使用此关键字访问 int y,那么编译器会得到一个歧义,因为静态 int y 是由所有对象共享的。您可以使用类名访问静态变量。

1赞 ayush prashar 4/16/2021 #9

静态方法为静态字段设置值没有问题。

唯一的问题是使用此关键字。请注意,由于静态方法是在类加载时处理的,因此几乎可以肯定在时间点不存在“this”,这就是为什么在静态上下文中不允许使用此关键字的唯一逻辑原因。

另一方面,静态方法可以从对象调用,因为它可供对象访问。静态数据成员和行为背后的意图是使其对该类的所有实例通用。

0赞 Siddharth Mittal 9/24/2023 #10

让我们通过一个简单的例子来理解

示例 1

public class Sample{
   static int num = 50;
   public static void demo(){
      System.out.println("Contents of the static method");
   }
   public static void main(String args[]){
      Sample.demo();
   }
}

输出

Contents of the static method

示例 2

public class Sample{
   static int num = 50;
   public static void demo(){
      System.out.println("Contents of the static method"+this.num);
   }
   public static void main(String args[]){
      Sample.demo();
   }
}

输出

error: non-static variable this cannot be referenced from a static context

总结 明智地观察示例 2 ,您将知道您将获得 CTE。这两个示例都将帮助您了解其中的区别

不断学习,不断成长

0赞 Md Zunaid Akhtar 10/31/2023 #11

'this' 关键字用于存储对象的地址/引用。 对于静态方法,只分配一次内存,但是在非静态内存的情况下,每次创建对象时都会分配每个对象具有不同的地址。 因此,要唯一地访问每个对象,我们需要地址,而这个关键字可以帮助我们做到这一点。 对于静态方法,只存在一个副本,意味着只有一个引用,我们可以在没有对象引用的情况下访问静态成员。

评论

0赞 Community 10/31/2023
您的答案可以通过额外的支持信息得到改进。请编辑以添加更多详细信息,例如引文或文档,以便其他人可以确认您的答案是正确的。您可以在帮助中心找到有关如何写出好答案的更多信息。