“双花括号初始化”介绍
在Java中,双花括号初始化(也称为“双括号初始化”或“匿名内部类初始化”)是一种快速初始化集合或数组的便捷写法。这种方法特别适用于在不需要显式声明变量类型或构造方法的情况下,快速填充集合或数组。例如:
ArrayList<String> list = new ArrayList<String>() {{
add("A");
add("B");
add("C");
}};
Map map = new HashMap() {{
put("Name", "Unmi");
put("QQ", "1125535");
}};
“双花括号初始化”原理
这里以ArrayList的例子解释,首先第一层花括号定义了一个继承于ArrayList的匿名内部类 (Anonymous Inner Class),第二层花括号实际上是这个匿名内部类实例初始化块 (Instance Initializer Block)(或称为非静态初始化块)。
此初始化方式实际上创建了一个新类型的实例。
“双花括号初始化”的类二进制序列化异常
示例代码如下:
@Data
public class User implements Serializable {
private String name;
}
public class MTest{
//运行通过
@Test
public void test1() throws IOException {
User user = new User();
user.setName("abc");
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(user);
}
//运行失败,报异常java.io.NotSerializableException
@Test
public void test2() throws IOException {
User user = new User() {{
setName("abc");
}};
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(user);
}
}
例子中User实现了Serializable接口,单元测试MTest.test1运行通过,MTest.test2运行失败,报java.io.NotSerializableException异常。
在开发过程中,我发现二进制序列化存在这个bug,而经过测试验证,FastJSON并未受此问题影响。这一bug是在使用flowable进行流程变量操作时被发现的。为了避免大家重蹈覆辙,特此分享这一经验。