当前位置:  开发笔记 > 编程语言 > 正文

为什么Java编译器不能解决这个问题呢?

如何解决《为什么Java编译器不能解决这个问题呢?》经验,为你挑选了2个好方法。

为什么编译器无法在以下示例中从Collections.emptySet()推断出结果的正确类型?

import java.util.*;
import java.io.*;

public class Test {
    public interface Option {
        public  B option(B b, F f);
    }

    public interface F {
        public B f(A a);
    }

    public Collection getColl() {
        Option iopt = null;

        return iopt.option(Collections.emptySet(), new F>() {
            public Collection f(Integer i) {
                return Collections.singleton(i.toString());
            }
        });
    }
}

这是编译器错误消息:

knuttycombe@knuttycombe-ubuntu:~/tmp/java$ javac Test.java 
Test.java:16: option(B,Test.F) in 
Test.Option cannot be applied to (java.util.Set,
>>)
            return iopt.option(Collections.emptySet(), new F>() {
                   ^
1 error

现在,getColl()的以下实现当然有效:

    public Collection getColl() {
        Option iopt = null;

        Collection empty = Collections.emptySet();
        return iopt.option(empty, new F>() {
            public Collection f(Integer i) {
                return Collections.singleton(i.toString());
            }
        });
    }

并且关于集合的类型安全方法的整个意图是避免单例集合的这种问题(而不是使用静态变量.)那么编译器是否无法跨多个泛型级别执行推理?这是怎么回事?



1> GaryF..:

Java需要通过推理进行大量的手工操作.类型系统可以在很多情况下更好地推断,但在您的情况下,以下将起作用:

print("Collections.emptySet();");



2> martinus..:

首先,您可以将问题范围缩小到以下代码:

public class Test { 
    public void option(Collection b) {
    }

    public void getColl() {
        option(Collections.emptySet());
    }
}

这不起作用,需要一个临时变量,否则编译器无法推断出类型.以下是对此问题的一个很好的解释:为什么临时变量在调用泛型方法时很重要?

推荐阅读
雨天是最美
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有