嘿,长时间听众第一次打电话,我问一个与Java反射相关的问题,以及它是多么容易让自己看起来很丑陋的编码.下面的方法尝试获取两个相似的对象(一个对象具有另一个对象的所有字段,然后是一些对象),并将它们中的两个进行比较以获得相等性.如果对象共享的getter相等,它将(据称)返回true,如果它们不相等则返回false.
public boolean validateArchive( Object record, Object arcRecord ) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException
{
log.debug( record.getClass().toString() );
Object methodValue;
Object arcMethodValue;
for ( Method method : record.getClass().getMethods() )
{
if ( method.getTypeParameters().length == 0 && method.getName().startsWith( "get" ) && !method.getName().startsWith( "getClass" ) )
{
methodValue = method.invoke( record );
arcMethodValue = arcRecord.getClass().getMethod( method.getName() ).invoke( arcRecord );
log.debug( "Method name: " + method.getName() );
log.debug( "Archive value: " + arcMethodValue );
log.debug( "Object value: " + methodValue );
if ( arcMethodValue != null && methodValue != null && !arcMethodValue.equals( methodValue ) )
{
return false;
}
else
{
if ( arcMethodValue == null && methodValue != null || methodValue == null && arcMethodValue != null )
{
return false;
}
}
}
}
return true;
}
Run Code Online (Sandbox Code Playgroud)
这个方法做了我期望它在单元测试中做的事情,但它看起来很难看,并且感觉不对(我特别不喜欢嵌套'if'的粉丝).我只是希望能有一些关于如何更有效/更有效地做到这一点的指示.如果我违反了某种发布规则,请随时纠正我,我渴望学习等等.
对于此特定任务,我建议在要比较的类中实现equals方法,除非您没有该选项(例如,如果您没有原始类的源代码).像IntelliJ这样的IDE提供了对"equals"和"hashcode"方法创建的支持(在IntelliJ中,您提供了将要比较的字段以及哪些字段可以为null或不为null).对于这个特殊情况,我会说使用这些工具.
有一种情况我认为使用Reflection的实现会很有用 - 在单元测试中,如果你想在相等不成立时抛出一个断言错误,你实际上可以为失败的确切字段抛出一个断言,并且不只是一个通用的"对象不一样"的断言错误 - 即使在这种情况下,我会在我的原始验证之后执行一个等于确保对象是相同的,或者至少是equals方法的实现和好好工作.
PS:如果你想摆脱所有这些编码检查Beans Common库; PS 2:反射也不错,它可以在任何没有显式代码调用的地方使用 - 例如Spring配置文件.只是不要滥用它.
| 归档时间: |
|
| 查看次数: |
832 次 |
| 最近记录: |