Java 谷歌为什么选择Guava';s ArrayListMultimap clear方法在被方法引用调用时抛出IllegaAccessError?

Java 谷歌为什么选择Guava';s ArrayListMultimap clear方法在被方法引用调用时抛出IllegaAccessError?,java,guava,method-reference,Java,Guava,Method Reference,演示故障的示例代码: package ia.quant.nextgen.entry; import com.google.common.collect.ArrayListMultimap; import java.util.function.Consumer; /** * Created by arpeke on 2015-12-18. */ public final class SampleMain { public static void main(String[] ar

演示故障的示例代码:

package ia.quant.nextgen.entry;

import com.google.common.collect.ArrayListMultimap;

import java.util.function.Consumer;

/**
 * Created by arpeke on 2015-12-18.
 */
public final class SampleMain {

    public static void main(String[] argArr) {

        final ArrayListMultimap<Void, Void> arrayListMultimap = ArrayListMultimap.create();
        arrayListMultimap.clear();

        final Consumer<ArrayListMultimap> arrayListMultimapConsumer = ArrayListMultimap::clear;
        arrayListMultimapConsumer.accept(arrayListMultimap);
    }
}
我正在使用32位Java8(v1.8.0_60)和GoogleGuavaV19.0。我的Google Fu告诉我Google Guice是根本原因,但缺乏可信的解释。(这是一个更大项目的一部分,该项目还包括通过ApacheMaven实现的Google Guice v3.0。)

样本参考:

有人知道吗

  • 根本原因
  • 变通办法
  • (最后,我还尝试了Google Guava v18.0,但没有成功。)

    更新 这段代码有效,但我不明白为什么。(我是否误解了非静态方法引用?)

    final Consumer arraylistmultimapsconsumer=x->x.clear();
    arrayListMultimapConsumer.accept(arrayListMultimap);
    
    lambda需要找到方法的最后一个定义。因此,当您编写
    ArrayListMultimap::clear
    时,解释器实际上会尝试查找上次定义方法
    clear
    的层次结构的哪个类。该方法最后一次定义是在
    AbstractMapBasedMultimap
    中,这是一个包私有类

    目前的问题很可能出现在JRE中,但存在两种解决方法

    第一个就是你描述的那个。第二种可能是Guava团队要么将
    AbstractMapBasedMultimap
    公开,要么在
    ArrayListMultimap
    中重新定义
    clear()
    方法(该方法只需要调用
    super.clear()

    目前对您来说,两种解决方法中最简单的一种是您尝试过的方法。如果我是你,我仍然会要求Guava团队制定他们自己的解决方案,这样就不会影响更多的用户


    关于您的解决方案,它之所以有效,是因为您使用了该方法而不是引用它。

    FYI:看起来OpenJDK最近解决了一个与此相关的问题:
    Exception in thread "main" java.lang.IllegalAccessError:
        tried to access class com.google.common.collect.AbstractMapBasedMultimap
        from class ia.quant.nextgen.entry.SampleMain
    at ia.quant.nextgen.entry.SampleMain.lambda$main$1(SampleMain.java:17)
    at ia.quant.nextgen.entry.SampleMain.main(SampleMain.java:18)
    
    final Consumer<ArrayListMultimap> arrayListMultimapConsumer = x -> x.clear();
    arrayListMultimapConsumer.accept(arrayListMultimap);