【问题标题】:Why can't we use 'this' keyword in a static method为什么我们不能在静态方法中使用“this”关键字
【发布时间】:2012-07-24 18:11:10
【问题描述】:
class Sub {
    static int y;
    public static void foo() {
         this.y = 10;
    }
}

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

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

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

【问题讨论】:

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

标签: java oop static this


【解决方案1】:

因为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;
    }
}

【讨论】:

  • 反对者可能认为这并不能真正回答问题,因为您基本上重复了 OP 已经知道的内容,并且只提供了一个冗长的解决方法。如果类命名为ThisClassHasAQuiteLongName,那么在静态方法中将该类称为this不是更好吗?
  • 这不是真的,我已经解释了为什么this 不能用于静态方法(因为没有类的实例被命名为this)并显示访问字段的两种方式。能够在静态上下文中使用this 作为类名的替换会误导和不一致(至少恕我直言)。不过,感谢您的反馈,这也可能是投反对票的原因。
  • 这个问题,据我了解,我也想知道,为什么 Java 不会在静态上下文中重载 this 的含义来表示类,而不是 Sub.y可以键入this.y。这似乎是一个明显的设计选择,因为它消除了明确提及类名的需要,这可能会改变。一般来说,当有人问“为什么在不同的上下文中 x 被定义为 y 而不是 z”时,它并不令人满意,而且回答“因为它被定义为 y”确实有点有毒和居高临下。想知道同样的事情让我感到很愚蠢,因为我仍然如此。
  • @AndrewCone 感谢您的反馈。你提出了一个很好的观点(关于我为什么被否决)。关于主题:我认为原因是 Java 专注于拥有(或至少试图拥有)一个干净的面向对象结构。当您重载关键字时,可读性会受到影响。根据当前定义,当您阅读this.y 时,您知道,它是一个局部变量而不是静态变量。所以它更干净。
【解决方案2】:

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

this :- "this" 表示当前类 OBJECT ,所以很明显 "this" 只会出现 我们打算创建该类的对象时的图片。

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

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

【讨论】:

  • 你刚才提到Java有一条规则是不使用类实例来调用静态字段。没有这样的 Java 规则,而是有一些特定的原因“静态字段/方法仅在编译时创建并存储在名为 PermGen 的内存区域中。静态的东西只是类的一部分,所以我们可以访问直接使用类名,无需创建实例来访问它们”。
【解决方案3】:

this 指的是对象Sub 的这个实例。由于方法是static,所以没有Sub的实例。

【讨论】:

    【解决方案4】:

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

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

    您可以在静态方法中设置静态字段,但您无法在静态方法中访问this,因为this 代表对象的当前实例,而在静态方法中您没有实例。

    【讨论】:

    • 您愿意解释一下我的回答或@Peter 的回答有什么问题吗?
    • 你的回答没有错。再次将其投票为0。 (由于糟糕的投票代表系统,你的代表总数为 +8 ^^)
    【解决方案5】:

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

    【讨论】:

      【解决方案6】:

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

      【讨论】:

        【解决方案7】:

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

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

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

        【讨论】:

          【解决方案8】:

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

          【讨论】:

            【解决方案9】:

            当我们声明变量和方法是静态的,那么 this 被对象共享,其中 this 关键字只指向当前对象。假设您已经创建了 foo 类的五个对象,然后所有对象都只创建了一个由 (int y) 制成的副本。因此,如果您使用此关键字访问 int y,则编译器会不确定哪个对象必须指向,因为静态 int y 是共享的被所有人反对。您可以使用类名访问静态变量。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2010-11-01
              • 2014-07-01
              • 1970-01-01
              相关资源
              最近更新 更多