首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >此代码使用ecj进行编译,但不使用javac。这是ecj,javac中的一个bug,还是两者都不是?

此代码使用ecj进行编译,但不使用javac。这是ecj,javac中的一个bug,还是两者都不是?
EN

Stack Overflow用户
提问于 2018-04-10 21:01:13
回答 1查看 239关注 0票数 12

下面的代码创建一个生成CollectorUnmodifiableSortedSet

代码语言:javascript
复制
package com.stackoverflow;

import java.util.Collections;
import java.util.SortedSet;
import java.util.TreeSet;
import java.util.stream.Collector;
import java.util.stream.Collectors;

public class SOExample {

    public static <T extends Comparable<T>> Collector<T, ?, SortedSet<T>> toSortedSet() {
        return Collectors.toCollection(TreeSet::new);
    }

    public static <T extends Comparable<T>> Collector<T, ?, SortedSet<T>> toUnmodifiableSortedSet() {
        return Collectors.collectingAndThen(toSortedSet(), Collections::<T> unmodifiableSortedSet);
    }
}

这些代码在ecj编译器下编译:

代码语言:javascript
复制
$ java -jar ~/Downloads/ecj-3.13.101.jar -source 1.8 -target 1.8 SOExample.java
Picked up _JAVA_OPTIONS: -Duser.language=en -Duser.country=GB

然而,在javac下:

代码语言:javascript
复制
$ javac -version
Picked up _JAVA_OPTIONS: -Duser.language=en -Duser.country=GB
javac 1.8.0_73

$ javac SOExample.java
Picked up _JAVA_OPTIONS: -Duser.language=en -Duser.country=GB
SOExample.java:16: error: method collectingAndThen in class Collectors cannot be applied to given types;
        return Collectors.collectingAndThen(toSortedSet(), Collections::<T> unmodifiableSortedSet);
                         ^
  required: Collector<T#1,A,R>,Function<R,RR>
  found: Collector<T#2,CAP#1,SortedSet<T#2>>,Collection[...]edSet
  reason: cannot infer type-variable(s) T#3
    (actual and formal argument lists differ in length)
  where T#1,A,R,RR,T#2,T#3 are type-variables:
    T#1 extends Object declared in method <T#1,A,R,RR>collectingAndThen(Collector<T#1,A,R>,Function<R,RR>)
    A extends Object declared in method <T#1,A,R,RR>collectingAndThen(Collector<T#1,A,R>,Function<R,RR>)
    R extends Object declared in method <T#1,A,R,RR>collectingAndThen(Collector<T#1,A,R>,Function<R,RR>)
    RR extends Object declared in method <T#1,A,R,RR>collectingAndThen(Collector<T#1,A,R>,Function<R,RR>)
    T#2 extends Comparable<T#2>
    T#3 extends Object declared in method <T#3>unmodifiableSortedSet(SortedSet<T#3>)
  where CAP#1 is a fresh type-variable:
    CAP#1 extends Object from capture of ?
1 error

如果我将违规行更改为以下内容,代码将在这两个编译器下编译:

代码语言:javascript
复制
return Collectors.collectingAndThen(toSortedSet(), (SortedSet<T> p) -> Collections.unmodifiableSortedSet(p));

这是ecj、javac中的一个bug,还是允许这两种行为的欠规范?

Javac在java 9和10中的行为是相同的。

EN

回答 1

Stack Overflow用户

发布于 2018-04-10 21:19:36

有趣的是,它不需要toSortedSet就可以编译

代码语言:javascript
复制
public static <T extends Comparable<T>> Collector<T, ?, SortedSet<T>> toUnmodifiableSortedSet() {
    return Collectors.collectingAndThen(Collectors.toCollection(TreeSet::new), Collections::<T>unmodifiableSortedSet);
}

如果您显式地将T传递给toSortedSet (移除static并使用this.<T>toSortedSet()也同样有效),它也会编译:

代码语言:javascript
复制
public static <T extends Comparable<T>> Collector<T, ?, SortedSet<T>> toUnmodifiableSortedSet() {
    return Collectors.collectingAndThen(Test.<T>toSortedSet(), Collections::<T>unmodifiableSortedSet);
}

关于为什么不按原样编译的问题,我怀疑这与两个方法之间的捕获类型不相同有关,而且toSortedSet需要toUnmodifiableSortedSet中使用的相同类型的T (因为您为这两个方法定义了泛型类型T )。

我进一步相信这就是原因所在,因为您可以为您的T定义一个泛型类型class,并在这两种方法中使用它(如果您删除static):

代码语言:javascript
复制
public class Test<T extends Comparable<? super T>> {
    public static void main(String[] args) throws Exception {
        System.out.println(Stream.of(5, 3, 4, 2, 1, 5, 4, 3, 2, 1)
            .collect(new Test<Integer>().toUnmodifiableSortedSet()));
    }

    public Collector<T, ?, SortedSet<T>> toSortedSet() {
        return Collectors.toCollection(TreeSet::new);
    }

    public Collector<T, ?, SortedSet<T>> toUnmodifiableSortedSet() {
        return Collectors.collectingAndThen(toSortedSet(), Collections::unmodifiableSortedSet);
    }
}

上面的编译和运行都很好。

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

https://stackoverflow.com/questions/49762791

复制
相关文章

相似问题

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