Ale*_*sky 21 java generics instance-initializers
我有一些静态初始化代码:
someMethodThatTakesAHashMap(new HashMap<K, V>() {
{
put("a","value-a");
put("c","value-c");}
});
Run Code Online (Sandbox Code Playgroud)
出于某种原因,我收到了Eclipse的警告:serializable类没有声明静态的最终serialVersionUID.
这是抱怨匿名课吗?我能做些什么,或者我应该压制它.
Pas*_*ent 28
您正在使用的语法称为双括号初始化 - 实际上是" 实例初始化块,它是匿名内部类的一部分 "(当然不是黑客).因此,在使用此表示法时,您实际上是在定义一个新类(!).
您的案例中的"问题"是HashMap实现Serializable.此接口没有任何方法,仅用于标识可序列化的语义.换句话说,它是一个标记界面,你具体地不需要实现任何东西.但是,在反序列化期间,Java使用名为a的版本号serialVersionUID来验证序列化版本是否与目标兼容.如果您不提供此项serialVersionUID,则会计算出来.并且,正如javadoc中所记录的那样Serializable,计算出的值非常敏感,因此建议明确声明它以避免任何反序列化问题.这就是Eclipse"抱怨"的原因(注意这只是一个警告).
因此,要避免此警告,您可以添加serialVersionUID到您的匿名内部类:
someMethodThatTakesAHashMap(new HashMap<String, String>() {
private static final long serialVersionUID = -1113582265865921787L;
{
put("a", "value-a");
put("c", "value-c");
}
});
Run Code Online (Sandbox Code Playgroud)
但是你松开了语法的简洁性(你可能甚至不需要它).
因此,另一个选择是通过向@SuppressWarnings("serial")您调用的方法添加a来忽略警告someMethodThatTakesAHashMap(Map).在您的情况下,这似乎更合适.
尽管如此,虽然这种语法简洁,但它有一些缺点.首先,如果对使用双括号初始化初始化的对象持有引用,则隐式保存对外部对象的引用,该引用不符合垃圾回收的条件.所以要小心.第二(这听起来像微优化),双支撑初始化有一点点开销.第三,这种技术实际上使用了我们所看到的匿名内部类,因此吃了一些permgen空间(但我怀疑这确实是一个问题,除非你真的滥用它们).最后 - 这可能是最重要的一点 - 我不确定它是否使代码更具可读性(它不是一个众所周知的语法).
因此,虽然我喜欢在测试中使用它(为了简洁),但我倾向于避免在"常规"代码中使用它.
是的,你可以抑制警告,但我会像这样重写它:
HashMap<String, String> map = new HashMap<String, String>();
map.put("a","value-a");
map.put("c","value-c");
someMethodThatTakesAHashMap(map);
Run Code Online (Sandbox Code Playgroud)
IMO不需要抑制,也不需要阅读.
| 归档时间: |
|
| 查看次数: |
17813 次 |
| 最近记录: |