qua*_*tum 0 java serialization
在编写一个简单的远程测试时,我遇到了一个涉及DBI(双括号初始化)的令人惊讶的情况,我一直无法完全理解,所以我会请求一些帮助.
请考虑以下代码:
public class RemotingTest {
@Autowired
private RemotingTestController remotingTestController;
//DBI
List<SomeBean> mockList = new ArrayList<SomeBean>(){{
add(MockFactoryBean.getMockBean());
}};
@Test
public void testRemoting() {
try {
// controller code is not relevant - it simply passes this list
// via Spring's HttpInvokerProxyFactoryBean to a session facade which then
// passes the list further down the SOA stack...
String result = remotingTestController.createBeanRemotely(mockList);
log.debug(result);
} catch (Exception e) {
fail();
e.printStackTrace();
}
}
Run Code Online (Sandbox Code Playgroud)
}
此代码在运行时发生爆炸,出现以下错误,这对我没有意义:
java.io.NotSerializableException: org.stackoverflow.RemotingIntegrationTest at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1164) at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1518) <<stacktrace snipped>> at org.springframework.remoting.httpinvoker.HttpInvokerClientInterceptor.executeRequest(HttpInvokerClientInterceptor.java:174) at org.springframework.remoting.httpinvoker.HttpInvokerClientInterceptor.invoke(HttpInvokerClientInterceptor.java:142) ... 33 more
但是,如果我只是省略DBI并使用vanilla样式模式将元素添加到列表中,如下所示:
public class RemotingTest {
@Autowired
private RemotingTestController remotingTestController;
List<SomeBean> mockList = new ArrayList<SomeBean>();
@Test
public void testRemoting() {
mockList.add(MockFactoryBean.getEcopStatusMock());
try {
//this block stays the same
} catch (Exception e) {
//.....
}
}
Run Code Online (Sandbox Code Playgroud)
}
一切正常,序列化顺利.我甚至试图使测试 Serializable(颤抖),但是没有产生任何结果,因为测试死于一个更有趣的错误 - HttpInvokerServiceExporter应该实现Serializable :)
问题是 - 为什么会这样?研究DBI有点让我相信通过向列表添加元素,这种方式实际上产生了两个对象 - 期望的ArrayList<T>()和包含添加元素的新子类 ArrayList<T>()对象; 这在某种程度上混淆了Spring的Remoting并且死于NotSerializableException的可怕死亡.
然而,我不确定,如果这是幕后发生的事情,那么任何帮助解释这一点都将不胜感激.
环境使用以下内容:
发生这种情况是因为双括号初始化语法创建了一个匿名子类ArrayList,并且像所有匿名类一样,它包含对其父对象的隐式引用(在本例中为您的测试).
为了可序列化,父对象(即您的测试)也必须是可序列化的.这显然不是你想要的.你只需要避免使用这种语法,方便的想法就是这样.
列表同样方便的替代方案是:
List<SomeBean> mockList = Arrays.asList(
bean1, bean2, bean3
);
Run Code Online (Sandbox Code Playgroud)
在构建Maps时,DBI语法才真正引人注目.
| 归档时间: |
|
| 查看次数: |
492 次 |
| 最近记录: |