使用 Java 8 构造时创建 Bean 时出现 ArrayOutOfBoundsException
Posted
技术标签:
【中文标题】使用 Java 8 构造时创建 Bean 时出现 ArrayOutOfBoundsException【英文标题】:ArrayOutOfBoundsException on Bean creation while using Java 8 constructs 【发布时间】:2015-08-24 02:22:25 【问题描述】:当我使用 Java 8 功能时,我在服务启动(创建 Bean)时收到 ArrayIndexOutOfBoundsException
。
Java 8 已经设置好并且一直在工作。代码编译正确。在服务启动时,服务无法侦听端口,因为没有创建 bean。当我更改代码(删除 java 8 构造)时,服务启动并且一切正常。
这是我正在使用的代码(服务启动的工作代码):
for (Item itemObject : response)
if (itemObject.hasId())
idList.add(String.valueOf(itemObject.Id());
使用 Java 8 构造的相同代码:
response.parallelStream()
.filter(itemObject -> itemObject.hasId())
.map(itemObject -> itemObject.getId())
.forEach(id -> idList.add(id));
包含这段代码的类的 bean 是使用组件扫描创建的。
以下是使用第二个代码块代替第一个代码块时的异常消息:
Exiting with throwable: java.lang.IllegalArgumentException: org.springframework.beans.factory.BeanDefinitionStoreException: Failed to read candidate component class: URL [jar:file:/workspace/.../GetContainerIdForFcSkuAdapter.class]; nested exception is java.lang.ArrayIndexOutOfBoundsException: 51880
java.lang.IllegalArgumentException: org.springframework.beans.factory.BeanDefinitionStoreException: Failed to read candidate component class: URL [jar:file:/workspace....Some.class]; nested exception is java.lang.ArrayIndexOutOfBoundsException: 51880
对我来说没有意义的是,为什么在创建 bean 时会覆盖函数内的代码(它不是 bean 类的构造函数)。我问这个,因为当我使用正常的 for 循环而不是并行流时,不存在异常。当调用函数并且实际使用此代码时,不应该出现ArrayOutOfBoundsException
。
我该如何解决这个问题?
【问题讨论】:
什么是idList
?在第二个版本中,您使用的是parallelStream
,因此您正在从多个线程将项目添加到此列表中。您使用的列表实现是线程安全的吗?如果您使用stream()
而不是parallelStream()
,错误会消失吗?
另外,在列表中获取流内容的正常方法是List<Something> list = stream.collect(Collectors.toList())
,而不是stream.forEach(o -> list.add(o)
。
我并不是真的从多个线程添加。 Java 在内部展开循环并进行并行化。使用蒸汽时仍然存在错误。就像我说的,代码块应该在调用函数时执行,而不是在创建 bean 时执行。如何使用此块并在服务启动时提供 ArrayIndexOutOfBounds。请在下面查看我的答案,并告诉我您是否认为这可能是一个原因
【参考方案1】:
您使用哪个版本的 Spring?您需要升级到 Spring 4 才能使用 Java 8 lambda 表达式。
【讨论】:
是的,我最近在使用 Spring 3.0.5 时发现了一个错误,该错误似乎已在 4.0.5 中修复。以下是详细信息。
如果您的类具有参数化构造函数,并且还具有使用 lambda 表达式的方法(在 Java 8 中引入),则在为该类创建 bean 时会发生 ArrayIndexOutOfException。
【讨论】:
这并不是真正的错误。 Spring 3 不完全支持 Java 8,因此在 Spring 3.0.5 中使用 Lambdas 是用户错误,而不是 Spring 错误。 我刚遇到这个,看起来非常奇怪。正如你所说,当我向 bean 的构造函数添加一个参数时,它就发生了。我在几个地方使用了 forEach。我认为我永远不会建立这样的联系,即类中的任何地方的 forEach 都会以数组边界异常破坏其 bean 实例化。哦,好吧——谢谢,Stack Overflow! 你让我摆脱了噩梦般的头痛!谢谢! 我遇到了同样的问题,但情况有点不同。我的类没有任何参数化构造函数,但在一个函数中使用 lambda 表达式。我尝试将 spring 升级到 v4,但没有帮助。删除 lambda 表达式确实有效。这是一个奇怪的问题!谁能解释为什么会发生这种情况?以上是关于使用 Java 8 构造时创建 Bean 时出现 ArrayOutOfBoundsException的主要内容,如果未能解决你的问题,请参考以下文章
使用 Spring 注入 bean 时出现 nullPointerException
Android - 使用改造时出现错误“无法构造实例(尽管至少存在一个创建)”
Windows Phone 8.1 - 从后台任务创建 WriteableBitmap 时出现异常
创建 EntityManagerFactory 时出现 ArrayIndexOutOfBoundsException
创建 ElasticSearchRepository 时出现 BeanCreationException - 无法解析匹配的构造函数