gpt4 book ai didi

java - 为什么 MyClass.class 存在于 java 而 MyField.field 不存在?

转载 作者:行者123 更新时间:2023-11-30 07:35:25 25 4
gpt4 key购买 nike

假设我有:

class A {
Integer b;
void c() {}
}

为什么Java有这样的语法:A.class,而没有这样的语法:b.field, c.method?

类字面量是否有如此普遍的用途?

最佳答案

A.class 语法看起来像一个字段访问,但实际上它是在根本不允许正常字段访问的上下文中的特殊语法规则的结果;即 A 是一个类名。

这是 JLS 中的语法:

Primary:
ParExpression
NonWildcardTypeArguments (
ExplicitGenericInvocationSuffix | this Arguments)
this [Arguments]
super SuperSuffix
Literal
new Creator
Identifier { . Identifier }[ IdentifierSuffix]
BasicType {[]} .class
void.class

请注意,fieldmethod 没有等效的语法。

(旁白:语法允许 b.field ,但 JLS 声明 b.field 表示名为“字段”的字段的内容......如果不存在这样的字段,则为编译错误。同上 c.method ,此外字段 c 必须存在。所以这些结构都不是你想要的意思......)

为什么存在这个限制?好吧,我猜是因为 Java 语言设计者没有看到需要使语言语法/语义困惑以支持方便地访问 Field 和 Method 对象。 (请参阅下面的 *,了解更改 Java 以允许您想要的一些问题。)

Java 反射并不是为了易于使用而设计的。在 Java 中,最好尽可能使用静态类型。它效率更高,而且不那么脆弱。将反射的使用限制在静态类型根本不起作用的少数情况下。

如果您习惯于使用一切都是动态的语言进行编程,这可能会让您感到厌烦。但你最好不要与它作斗争。

Is there any use that is so common for class literals?

我想,他们支持类这样做的主要原因是它避免了程序在每次需要反射性地做某事时调用 Class.forName("some horrible string")。您可以称之为对反射(reflection)可用性的妥协/小让步。

我想另一个原因是 <type>.class 语法没有破坏任何东西,因为 class 已经是一个关键字。 (IIRC,语法是在 Java 1.1 中添加的。)


* 如果语言设计者试图改进对这种事情的支持,就会出现各种各样的问题:

  • 这些变化会给语言带来歧义,使编译和其他依赖于解析器的任务变得更加困难。
  • 无论 methodfield 是否变成关键字,这些更改无疑会破坏现有代码。
  • 您不能将 b.field 视为隐式对象属性,因为它不适用于对象。而 b.field 需要应用于字段/属性标识符。但是除非我们将 field 设为保留字,否则会出现异常情况,您可以创建一个名为 field 的字段,但您不能在 Java 源代码中引用它。
  • 对于 c.method ,存在一个问题,即可以有多个称为 c 的可见方法。第二个问题是,如果有一个名为 c 的字段和一个名为 c 的方法,则 c.method 可能 是对 method 引用的对象上名为 c字段 的引用领域。

关于java - 为什么 MyClass.class 存在于 java 而 MyField.field 不存在?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4485875/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com