【发布时间】:2012-12-26 01:50:45
【问题描述】:
在阅读和扫描旧代码时,我看到了这些代码行:
public static void replaceNull(Object obj)
{
if (obj == null)
{
return;
}
Field[] fields = obj.getClass().getDeclaredFields();
if (fields != null)
{
for (Field field : fields)
{
field.setAccessible(true);
Class<?> fieldType = field.getType();
try
{
if (field.get(obj) == null)
{
setDefaultValue(obj, field, fieldType);
}
} catch (IllegalArgumentException e)
{
logger. error("failed replacing null :"+ e.getMessage(),e);
} catch (IllegalAccessException e)
{
logger. error("failed replacing null :"+ e.getMessage(),e);
}
}
}
}
private static void setDefaultValue(Object obj, Field field, Class<?> fieldType) throws IllegalAccessException
{
if (fieldType == String.class)
{
field.set(obj, CommonConstants.BLANK);
} else if (fieldType == Date.class)
{
field.set(obj, new Date());
} else if (fieldType == Long.class)
{
field.setLong(obj, 0L);
} else if (fieldType == Integer.class)
{
field.setInt(obj, 0);
} else if (fieldType == BigDecimal.class)
{
field.set(obj, new BigDecimal("0.0"));
}
}
从程序的流程来看,作者似乎想为对象的所有数据成员创建一个默认值,如果值为空。
在使用 FindBugs 扫描时,findbugs 报告“DP_DO_INSIDE_DO_PRIVILEGED”,并在 setAccessible(true) 上有此描述:
不好的做法 - 调用的方法只能在 doPrivileged 块内调用 插件:findbugs 键:DP_DO_INSIDE_DO_PRIVILEGED 此代码调用需要安全权限检查的方法。如果此代码将被授予安全权限,但可能被没有安全权限的代码调用,则调用需要在 doPrivileged 块内进行。
我的问题为什么这么糟糕?又该如何解决呢?
【问题讨论】:
-
field.setAccessible(true); 需要
suppressAccessChecks权限。您可以通过AccessController.doPrivileged(...)将整个代码包装在PrivilegedAction中来“解决”该案例。或者忽略来自 FindBugs 的这个警告。并非所有错误/警告在任何情况下都有效。此外,整个函数可能已经被包装,但通常 FindBugs 无法检测到。