为什么MyClass.class存在于java和MyField.field中不存在?

osh*_*hai 2 java syntax

比方说我有:

class A {
    Integer b;
    void c() {}
}
Run Code Online (Sandbox Code Playgroud)

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

对于文字文字有什么用处吗?

Ste*_*n C 6

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

这是JLS中的语法所说的:

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

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

(旁白:语法允许b.field,但是JLS声明这b.field意味着名为"field"的字段的内容......如果不存在这样的字段,那么它就是编译错误.同上c.method,还有一个字段 c必须存在.所以这些结构都不代表你想要的意思......)

为什么存在这种限制?好吧,我想因为Java语言设计者没有看到需要混淆语言语法/语义来支持方便地访问Field和Method对象.(有关更改Java的一些问题,请参阅下面的*以获得您想要的内容.)

Java反射的设计并不容易使用.在Java中,最好在可能的情况下使用静态类型.它更有效,更不易碎.将反射的使用限制在静态类型不起作用的少数情况下.

如果你习惯于编程到一切都是动态的语言,这可能会让你烦恼.但你最好还是不打它.

对于文字文字有什么用处吗?

我猜,他们支持这类课程的主要原因是它避免了Class.forName("some horrible string")每次你需要反思性地做某些事情的程序.你可以称之为妥协/小小的让步,可用于反思.

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


*如果语言设计者试图改进对此类事物的支持,那么会出现各种各样的问题:

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