gpt4 book ai didi

Java 8 双大括号初始化和名称冲突

转载 作者:行者123 更新时间:2023-12-03 06:13:54 24 4
gpt4 key购买 nike

以下类有一个名为 Entry 的内部类。此代码不会在 Java 8 中编译,因为编译器假定双花括号初始值设定项中引用的 Entry 类型为 Map.Entry 而不是 Scope.Entry。该代码可以在 JDK 的早期版本(至少 6 和 7)中编译,但在 JDK 8 中被破坏。我的问题是“为什么?” Map.Entry 未在此类中导入,因此编译器没有理由假定该值的类型为 Map.Entry。是否引入了一些隐式作用域或匿名类的某些东西?

错误:

scope/Scope.java:23: error: incompatible types: scope.Scope.Entry cannot be converted to java.util.Map.Entry for (final Entry entry : entries) {
scope/Scope.java:22: error: cannot find symbol put(entry.getName(), entry);

示例代码:

package scope;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;

public class Scope {

public static class Entry<T> {
public String getName() {
return "Scope";
}
}

public static void main(String[] args) {
final Set<Entry> entries = new HashSet<>();

new HashMap<String, Entry>() {{
// Why does the Java 8 compiler assume this is a Map.Entry
// as it is not imported?
for (final Entry entry : entries) {
put(entry.getName(), entry);
}
}};
}
}

最佳答案

这绝对不是一个错误,而是使用双括号初始化的副作用。

new HashMap<String, Entry>() {{
for (final Entry entry : entries) {
put(entry.getName(), entry);
}
}};

这种类型的初始化基本上是一种巧妙的滥用方式instance initialization blocks 。它使用初始化 block 创建 HashMap 的匿名子类,然后在调用它之前将该 block 复制到其默认构造函数的开头。该子类优先考虑其父级范围内的 Entry,而不是其嵌套的范围。shadowing对此进行了解释。 .

来自8.1.6. Class Body and Member Declarations

If C itself is a nested class, there may be definitions of the same kind (variable, method, or type) and name as m in enclosing scopes. (The scopes may be blocks, classes, or packages.) In all such cases, the member m declared in or inherited by C shadows (§6.4.1) the other definitions of the same kind and name. [emphasis mine]

这里,C是声明的匿名内部类。由于它继承自 HashMap,因此 java.util.Map.Entry 会影响 scope.Scope.Entry

至于为什么它在以前的版本中按照你想要的方式编译,我不知道。这些版本中存在此行为(我引用的文档来自 7),因此它不应该起作用。所以也许这些版本存在缺陷。

关于Java 8 双大括号初始化和名称冲突,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26913341/

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