lambda表达式中的静态内部类:NoSuchMethodError访问$ 0

时间:2018-01-09 15:31:42

标签: java serialization lambda inner-classes nosuchmethoderror

考虑以下课程:内部静态类时间轴

public class TestClass implements Serializable {

    static class Timeline implements Serializable {

        private final CurrencyReference timelineCurrency;

        public Timeline(CurrencyReference timelineCurrency) {
            super();
            this.timelineCurrency = timelineCurrency;
        }

        public CurrencyReference getTimelineCurrency() {
            return timelineCurrency;
        }

        public void add(Day day, MoneyAmount amount) {

        }

    }

    private final Day minimumDay;
    private final Timeline totalStateTimeline;

    public TestClass(CurrencyReference stateCurrency, Day minimumDay) {
        super();
        totalStateTimeline = new Timeline(stateCurrency);
        this.minimumDay = minimumDay;
    }

    TestClass(Day minimumDay, Timeline totalStateTimeline) {
        super();
        this.minimumDay = minimumDay;
        this.totalStateTimeline = totalStateTimeline;
    }

    public void addConcentrationAmountEvents(Collection<? extends ConcentrationChangeEvent> events,
    Function<? super ConcentrationLimitStateKey, ? extends CurrencyReference> currencyFunction,
    BiFunction<MoneyAmount, CurrencyReference, MoneyAmount> conversionFunction) {
        events.stream().//
        filter(event -> !Decimal.ZERO.equals(event.getAmount().getAmount())).//
        forEach(event -> {
            Day businessDay = event.getDay().before(minimumDay) ? minimumDay : event.getDay();
            totalStateTimeline.add(businessDay, conversionFunction.apply(event.getAmount(), totalStateTimeline.getTimelineCurrency()));
        });
    }

}

在单元测试中执行方法addConcentrationAmountEvents时,它成功完成,没有任何问题。 另一方面,当将相同的部署到测试环境时,我得到以下异常:

 at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:208)        ...
 13 moreCaused by: 
java.lang.NoSuchMethodError: com.cache.TestClass$Timeline.access$0(Lcom/cache/TestClass$Timeline;)Lcom/datatype/CurrencyReference;
    at com.cache.TestClass.lambda$1(TestClass.java:221)
    at java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:184)
    at java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:175)
    at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1374)
    at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
    at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
    at java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:151)
    at java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:174)
    at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
    at java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:418)

行(TestClass.java:221)是

 totalStateTimeline.add(businessDay, conversionFunction.apply(event.getAmount(), totalStateTimeline.getTimelineCurrency()));

起初我试图直接访问Timeline.timelineCurrency,没有getter,但在这两种情况下错误都是一样的。 如果我通过getter访问该文件,为什么我需要生成访问$ 0方法?为什么在单元测试中不会出现此问题? 我非常感谢任何建议。 谢谢

编辑:

解除后,我注意到以下内容:

  static /* synthetic */ List access$0(TestClass.Timeline timeline) {
        return timeline.timeline;
    }

    static /* synthetic */ CurrencyReference access$1(TestClass.Timeline timeline) {
        return timeline.timelineCurrency;
    }

正如您所看到的那样,方法的名称是错误的,并且应该使用方法访问$ 1。我能在反编译的父类中看到这个吗?

1 个答案:

答案 0 :(得分:0)

根据Elite_Dragon1337和M. Prokhorov的建议,我能够找出问题所在。 实际上,在生产中,类已经手动修改,看起来像这样:     totalStateTimeline.add(businessDay,conversionFunction.apply(event.getAmount(),totalStateTimeline.timelineCurrency));

所以在反编译代码中它指的是

 static /* synthetic */ CurrencyReference access$0(TestClass.Timeline timeline) {
        return timeline.timelineCurrency;
    }
来自时间轴课程的

与此同时,父类被手动修改并直接在jar中更改,这改变了引用方法的名称。 我使用getter的解决方案是正确的,并删除了对合成方法的依赖,但jar没有正确部署(我不知道),所以问题仍然存在。 感谢您带领我走上正确的道路。