首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Java 8双花括号初始化和名称冲突

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

Stack Overflow用户
提问于 2014-11-14 00:12:10
回答 2查看 2K关注 0票数 19

下面的类有一个名为Entry的内部类。这段代码不能在Java8中编译,因为编译器假设双花括号初始化器中引用的EntryMap.Entry类型,而不是Scope.Entry类型。这段代码可以在JDK的早期版本(至少是6和7)中编译,但是在JDK8中被破坏了。我的问题是“为什么?”这个类中没有导入Map.Entry,因此编译器没有理由假设该值是Map.Entry类型。是否为匿名类引入了隐式作用域或其他内容?

错误:

代码语言:javascript
复制
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);

示例代码:

代码语言:javascript
复制
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);
            }
        }};
    }
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-11-14 02:53:12

这绝对不是一个bug,它是使用双花括号初始化的副作用。

代码语言:javascript
复制
new HashMap<String, Entry>() {{
    for (final Entry entry : entries) {
        put(entry.getName(), entry);
    }
}};

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

来自8.1.6. Class Body and Member Declarations

如果C本身是一个嵌套类,则在封闭的作用域中可能存在相同类型(变量、方法或类型)和名称为m的定义。(作用域可以是块、类或包。)在所有这些情况下,成员m在中声明或由C阴影继承(§6.4.1)相同种类和名称的其他定义。强调我的

这里,C是声明的匿名内部类。因为它继承自HashMap,所以java.util.Map.Entry隐藏了scope.Scope.Entry

至于为什么它在以前的版本中像你想要的那样编译,我不知道。这种行为在这些版本中就存在(我引用的文档来自7),所以它不应该工作。因此,也许这些版本是错误的。

票数 27
EN

Stack Overflow用户

发布于 2014-11-14 06:45:31

类型成员和隐藏的作用域对于编译器来说是一个困难的地方。有/有许多与此相关的bugs -主要是关于嵌套/内部/匿名类型。我找不到关于这个问题的确切信息,但我知道一些可以与之相关的信息。Here的情况与此非常相似(类型变量而不是封闭类型)。

关于规范中关于阴影的内容,还有一个issue。它引用了JLS并描述了什么是不理想的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26913341

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档