问题标签 [jls]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
2 回答
365 浏览

java - Java 语言规范和 VM 规范的早期版本是否可以在线获得?

Oracle 在http://docs.oracle.com/javase/specs/上有最新版本的 java 规范,但我找不到旧版本。这些存档在任何地方吗?

0 投票
3 回答
14932 浏览

java - Java 类名区分大小写

如果一个人在不同的目录中使用相同的不区分大小写的名称编写两个公共 Java 类,那么这两个类在运行时都不可用。(我在 Windows、Mac 和 Linux 上使用多个版本的 HotSpot JVM 进行了测试。如果有其他 JVM 可以同时使用它们,我不会感到惊讶。)例如,如果我创建一个名为的类a,并且一个命名A如下:

我的网站上提供了三个包含上述代码的 Eclipse 项目。

如果尝试我像这样调用myCase两个类:

类型检查器成功了,但是当我运行由上面的代码直接生成的类文件时,我得到:

线程“主”java.lang.NoClassDefFoundError 中的异常:testcase/A(错误名称:testcase/a)

在 Java 中,名称通常区分大小写。一些文件系统(例如 Windows)不区分大小写,所以我对上述行为的发生并不感到惊讶,但它似乎是错误的。不幸的是,Java 规范对于哪些类是可见的很奇怪。Java 语言规范 (JLS),Java SE 7 版(第6.6.1 节,第 166 页)说:

如果一个类或接口类型被声明为 public,那么它可以被任何代码访问,只要声明它的编译单元(第 7.3 节)是可观察的。

在第 7.3 节中,JLS 以极其模糊的术语定义了编译单元的可观察性:

预定义包 java 及其子包 lang 和 io 的所有编译单元始终是可观察的。对于所有其他包,主机系统确定哪些编译单元是可观察的

Java 虚拟机规范同样含糊不清(第 5.3.1 节):

以下步骤用于使用引导类加载器加载并创建由 [二进制名称] N 表示的非数组类或接口 C [...] 否则,Java 虚拟机将参数 N 传递给引导类加载器以依赖于平台的方式搜索 C 的声称表示。

所有这些都导致了四个问题,按重要性降序排列:

  1. 是否可以保证每个 JVM 中的默认类加载器可以加载哪些类?换句话说,我能否实现一个有效但退化的 JVM,它不会加载除 java.lang 和 java.io 中的类之外的任何类?
  2. 如果有任何保证,上面示例中的行为是否违反了保证(即该行为是否是错误)?
  3. 有什么方法可以同时加载 HotSpotaA?编写自定义类加载器会起作用吗?
0 投票
2 回答
807 浏览

java - Java 语言规范的哪一部分描述了省略的可变参数的行为?

我正在寻找 Java 语言规范 (JLS) 的相关部分,该部分描述了调用变量 arity (vararg) 方法时的行为。

考虑方法:

如果我像这样调用该方法:

输出将如下所示:[]因为args在调用站点的省略已在方法中转换为空数组printVarArgs

我正在寻找定义这种行为的 JLS 的要点。我发现的最接近的是15.12.4.2 Evaluate Arguments,但它没有给出这个例子,我不确定这种情况是否真的被形式/数学描述所涵盖。

JLS 的哪一部分描述了在省略 vararg 时自动创建空数组?

0 投票
3 回答
531 浏览

java - Why do try/catch or synchronized in Java require a statement block?

Java allows for certain keywords to be followed by a statement or a statement block. For example:

compiles as well as

This is also true for keywords like for, while etc.

However, some keywords don't allow this. synchronized requires a block statement. Same for try ... catch ... finally, which requires at least two block statements following the keywords. For example:

works, but the following doesn't compile:

So why do some keywords in Java require a block statement, while others allow a block statement as well as a single statement? Is this an inconsistency in language design, or is there a certain reason for this?

0 投票
0 回答
80 浏览

java - JLS的“覆盖和隐藏要求”中子类的返回类型不兼容

引用 JLS

如果具有返回类型 R1 的方法声明 d1 覆盖或隐藏具有返回类型 R2 的另一个方法 d2 的声明,则 d1 必须是可替代 d2 的返回类型,否则会发生编译时错误。 此外,如果 R1 不是 R2 的子类型,则必须发出未经检查的警告(除非被抑制(第 9.6.1.5 节))。方法声明不得有与它覆盖或隐藏的任何方法冲突(第 8.4.6 节)的 throws 子句;否则,会发生编译时错误。

粗体句子是否与段落的第一部分相矛盾。

我可以在下面的 JLS 中读到这适用于通用返回,例如

List<String>返回类型被返回类型覆盖,List但 JLS 中的那句话仍然不排除这种情况,如果还有其他情况适用该句子,你能澄清一下吗?

0 投票
4 回答
1216 浏览

java - 双重检查锁定的乱序写入

在针对双重检查锁定场景的乱序写入提到的示例中(参考: IBM 文章Wikipedia 文章

我无法理解为什么在构造函数完全初始化之前 Thread1 会出现同步块的简单原因。根据我的理解,创建“new”和调用构造函数应该按顺序执行,并且在所有工作未完成之前不应释放同步锁。

请让我知道我在这里缺少什么。

0 投票
1 回答
87 浏览

java - 我应该如何向 Java 语言添加功能?

我在 Java 周围的其他语言中看到了一些简洁的特性,比如生成器和最近的“等待”特性,我尝试使用字节码操作来实现其中的一些。但是,我认为这些对于大多数开发人员来说已经足够整洁,可以将它们作为一种语言特性。我看过 kijaro 项目;但是,关于如何到达那里的文档似乎很少。所以,即使只是为了我自己的使用和好奇,我应该如何处理呢?

谢谢!

0 投票
2 回答
4331 浏览

java - java中的“qualified this”构造是什么意思?

Effective Java 中的项目“第 22 项:支持静态成员类而不是非静态”中,Josh Bloch 说:

非静态成员类的每个实例都隐含地与其包含类的封闭实例相关联。在非静态成员类的实例方法中,您可以调用封闭实例上的方法或使用限定的 this 构造获取对封闭实例的引用。

他所说的Qualified This Construct是什么意思?

0 投票
1 回答
5261 浏览

java - Java - 使用相同的方法和不同的返回类型实现多个接口

考虑以下代码:

这会导致编译错误AB

B 型和 A 型不兼容;都定义了另一个(),但返回类型不相关

我已经看到了这个SO question,并按照接受的答案中的不兼容示例进行操作 - 即

但是,在那种情况下,返回类型是真正不兼容的——返回类型不能既是 void 又是布尔值。然而,在我上面的例子中,another()返回类型AB是 anA和 a B,所以可以实现这两个扩展接口。

此外,看过 JLS(8.4.8、8.4.8.3、8.4.8.4)后,我不太明白为什么我上面的例子是非法的。谁能给我解释一下?

A其次,除了重复或B中的合同要求之外,是否有任何解决方案/解决方法AB

0 投票
2 回答
126 浏览

java - Java 编译器是否允许对静态调用进行流敏感?

这是来自 JLS 部分 8.4.8.2 的简短示例。

根据示例的讨论,运行的输出main()将是“晚安,迪克”。这是因为静态方法是根据调用它们的变量/表达式的静态类型来调用的。

这是我的问题:任何对流敏感的编译器都可以计算出s调用时存储的任何对象的类型必须始终为Sub,因此如果允许编译器使用该信息,即使调用静态方法也可能有一些动态绑定的感觉。为什么不允许这样做?Java 是否有明确的目标,即每个编译器都生成行为完全相同的字节码,还是有其他原因?