问题标签 [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 投票
1 回答
213 浏览

java - 擦除方法签名和方法的方式不同?

我遇到了一个示例,该示例表明在方法签名和方法上的擦除方式不同,但我不知道为什么/如何。JLS §8.4.8.3规定:

如果类型声明 T 具有成员方法 m1 并且存在在 T 中声明的方法 m2 或 T 的超类型,则编译时错误,并且满足以下所有条件:

  1. m1 和 m2 具有相同的名称。
  2. m2 可从 T 访问。
  3. m1 的签名不是 m2 签名的子签名(第 8.4.2 节)。
  4. m1 或某些方法 m1 覆盖(直接或间接)的签名与 m2 或某些方法 m2 覆盖(直接或间接)的签名具有相同的擦除。

给出的编译时错误示例

说明:

这是非法的,因为 D.id(Object) 是 D 的成员,C.id(String) 在 D 的超类型中声明,并且:

  • 这两个方法具有相同的名称,id
  • D 可以访问 C.id(String)
  • D.id(Object) 的签名不是 C.id(String) 的子签名
  • 这两种方法具有相同的擦除

前两点很明显,但我不明白解释的最后两点。如果第三点成立,这两种方法如何具有相同的擦除?从第三点来看,签名的擦除似乎是使用参数化类 C<String> 的方法(即 id(String) 而不是 id(T))完成的。如果是这种情况,那么这两个方法应该有不同的擦除,但是该示例表明方法擦除是在非参数化类上完成的。那么,擦除实际上是如何应用于方法签名和方法的呢?

0 投票
2 回答
289 浏览

java - Java 语言规范:符号的含义 |S|

我正在通过JLS 7了解类型转换Section 5.5.1

它说:给定一个编译时引用类型 S(源)和一个编译时引用类型 T(目标),如果由于以下规则而没有发生编译时错误,则存在从 S 到 T 的强制转换。如果 S 是类类型:

  • 如果 T 是类类型,那么|S| <: |T|,或 |T| <: |S| . 否则,会发生编译时错误。

他们在第 4.10 节中明确了 S 和 T 是否是两种类型,那么

  • S :> T表示 S 是 T 的超类型
  • S > T表示 S 是 T 的适当超类型,这意味着S :> TS != T

我无法找到|S|的含义 . 请帮助我理解|S|是什么意思 ? 它是指属性的数量和类型还是其他什么。我试图在JLS本身中搜索它,但找不到它的含义。提前致谢。

0 投票
3 回答
720 浏览

java - JLS 的哪一部分说匿名类不能有公共/受保护/私有成员类

考虑这段代码:

有一个匿名类,它有一个private成员字段和一个private成员方法。它已成功编译。

然后考虑这个:

有一个匿名类有一个private成员类。然而...

  • javac 说:error: modifier private not allowed here
  • Eclipse 说:Illegal modifier for the local class PrivateInnerClass; only abstract or final is permitted 真的是本地类吗?

什么?为什么匿名类不能有publicprotectedprivate(以下简称those成员类,但可以有those成员字段和方法?很困惑,我调查了 JLS。由于 Eclipse 所说的,我首先查看了本地类

14.3. 本地类声明

本地类是一个嵌套类(第 8节),它不是任何类的成员,并且有一个名称(第 6.2 节、第6.7节)。
如果本地类声明包含任何访问修饰符publicprotectedprivate( §6.6 ) 或修饰符( §8.1.1 ),则会出现编译时错误。static

所以本地类不能有those修饰符。但是PrivateInnerClass 匿名的成员Cloneable,所以它不是本地类,仍然可以有those修饰符。

然后我查看了类修饰符

8.1.1。类修饰符

访问修饰符public( §6.6 ) 仅适用于顶级类 ( §7.6 ) 和成员类 ( §8.5 ),而不适用于本地类( §14.3 ) 或匿名类 ( §15.9.5 )。
访问修饰符protectedprivate第 6.6 节)仅适用于直接封闭类或枚举声明(第 8.5 节)中的成员类。

ButPrivateInnerClass是一个成员类,并且它在一个直接封闭的类中,匿名Cloneable,所以它仍然可以those在理论上有修饰符。其他部分我也查了,还是没找到相关规定。

那么Java语言规范的哪一部分说匿名类的成员类不能有those修饰符?


额外说明1:一些答案争论成员类和本地类,所以我做了一个测试,可以得出结论(除非修饰符很重要):

  1. 匿名Cloneable既不是成员类也不是本地类
  2. PrivateInnerClass成员类,但不是本地类

以下是我的测试代码:


额外说明 2: 查看普通类的声明(JLS §8.1):

据我了解,当Identifier该类是 XXX 类时,§8.1.1所说的是限制修饰符 of Identifier,而不是限制其他声明中的修饰符ClassBodyof Identifier。否则,匿名类甚至不能有those成员字段和方法。

任何答案,尤其是不同意额外注释 2 的答案,都必须指出为什么those允许成员字段和方法。


附注3:如果您认为JLS没有这部分,您仍然需要提供可靠的文档来解释为什么those禁止成员类以及为什么those允许成员字段和方法。


0 投票
3 回答
1983 浏览

java - Java final 字段编译时常量表达式

以下文字来自 jls http://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.5.3

即便如此,仍有许多并发症。如果在字段声明中将最终字段初始化为编译时常量表达式(第 15.28 节),则可能不会观察到最终字段的更改,因为该最终字段的使用在编译时被常量表达式的值替换.

谁能给我更好的解释以上。我无法理解“可能无法观察到对最终字段的更改”的说法。可以借助示例。

0 投票
6 回答
32806 浏览

java - 对于 Java 接口中的常量,“public static final”是多余的吗?

这段代码:

编译并按我的预期工作。看起来这与以下内容相同:

对于 Java 接口中的常量,“public static final”是多余的吗?Java 1.1、1.2、1.3、1.4、...、1.8 是这样吗?还是在 Java 版本中发生了变化?

0 投票
3 回答
76 浏览

java - 在“Class”类对象上锁定实现以进行同步

我正在通过这个链接。根据这个 :

类锁实际上是作为对象锁实现的。当 JVM 加载一个类文件时,它会创建一个 java.lang.Class 类的实例。当您锁定一个类时,您实际上是在锁定该类的 Class 对象。

但是根据 java 规范,堆上所有相同类型(类)的对象共享一个 Class 对象。那么对于对象的多线程同步访问来说,这怎么可能呢?

0 投票
1 回答
223 浏览

java - 仅包含子包的按需进口申报

相关:当没有这样的类时,如何使用 ant/javac 编译“import pack.*”?

假设我们有给定的包结构

其中包parent只包含两个子包ab(包下没有类parent)。

import parent.*位于 以外的包中的代码parent用 Maven(即javac)编译会引发编译时错误。错误是:

包父级不存在

我查看了有关这种情况的 Java 语言规范(实际没有导入类型的按需导入声明)。JLS 关于按需进口声明的第 7.5.2 段似乎没有指定这种行为。

这是一个错误javac吗?我不是在问如何规避编译错误。我想知道为什么javac会抛出错误,因为我在 JLS 中找不到它应该的任何引用;让我相信这可能是一个错误。

我用JDK 1.4、1.6、1.7和1.8测试过,错误是一样的。

附带说明一下,在 Eclipse 中使用相同的代码没有编译错误(使用 Eclipse Indigo、Juno、Luna 和 Mars 测试)。

注意:我在“mavenizing”仅依赖 Eclipse 编译器的(旧)现有项目时遇到了这种行为。我花了一段时间才确定这是我得到的编译错误的根本原因。

0 投票
3 回答
7748 浏览

java - 通过反射改变最终变量,为什么静态和非静态最终变量之间存在差异

请参考以下代码。当我运行代码时,我能够更改最终非静态变量的值。但是,如果我尝试更改最终静态变量的值,那么它会抛出java.lang.IllegalAccessException.

我的问题是为什么在非静态最终变量的情况下也不抛出异常,反之亦然。为什么有区别?

0 投票
1 回答
96 浏览

java - JLS 6/7 的哪些更改导致以下带有集合和泛型的未经检查的代码在 Java 7 中工作?

以下代码

是正确的 Java(即使代码是可疑的)。使用javacand java6 它抛出

虽然它在使用javacjava7 时运行没有错误。

是语言更改、修复错误还是隐藏功能?

(注意:使用 Eclipse 编译的代码在检查的所有 Eclipse 版本上运行时都没有错误 - Helios 到 Kepler。)

0 投票
3 回答
826 浏览

java - 什么时候用 '==' 操作符比较对象和原语是合法的?

下面的(Java)代码合法吗?

它不会针对 JDK 6 编译,但在 7+ 上似乎很好。规格有变化吗?修复了一个错误吗?我一直在讨论http://bugs.eclipse.org/bugs/show_bug.cgi?id=416950并且可以在这个上进行任何一种方式。