为什么Google Guava的ArrayListMultimap clear方法在方法引用调用时会抛出IllegalAccessError?

时间:2015-12-26 15:18:53

标签: 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[] argArr) {

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

        final Consumer<ArrayListMultimap> arrayListMultimapConsumer = ArrayListMultimap::clear;
        arrayListMultimapConsumer.accept(arrayListMultimap);
    }
}

以下是我看到的Error(不是Exception):

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)

我正在使用带有Google Guava v19.0的32位Java 8(v1.8.0_60)。我的Google-Fu告诉我Google Guice是根本原因,但缺乏可信的解释。 (这是一个更大的项目的一部分,该项目还包括通过Apache Maven的Google Guice v3.0。)

示例参考:https://github.com/hierynomus/scannit/issues/7

有谁知道......?

  1. 根本原因
  2. 解决方法
  3. (最后,我也尝试了Google Guava v18.0,但没有运气。)

    更新

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

    final Consumer<ArrayListMultimap> arrayListMultimapConsumer = x -> x.clear();
    arrayListMultimapConsumer.accept(arrayListMultimap);
    

1 个答案:

答案 0 :(得分:4)

Lambdas需要找到方法的最后一个定义。因此,当您编写ArrayListMultimap::clear时,解释器实际上会尝试查找最后定义方法clear的层次结构的哪个类。碰巧该方法最后在AbstractMapBasedMultimap中定义,这是一个包私有类。

手头的问题很可能在JRE中,但存在两种解决方法。

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

此时最适合您的两种解决方法是您尝试过的解决方法。如果我是你,我仍然会要求Guava团队制定自己的解决方法,以免影响更多用户。

关于您的解决方法,它可行,因为您使用方法而不是引用