java.lang.ClassCastException:Z不能转换为java.lang.String

问题描述:

我在尝试运行Junit测试上的覆盖范围(EclEmma)时收到错误:java.lang.ClassCastException: Z cannot be cast to java.lang.String。如果我定期运行测试(没有覆盖),那么它就会通过。java.lang.ClassCastException:Z不能转换为java.lang.String

这是代码(类中的所有字段是Strings):

@Override 
public Map<String, String> getErrors() throws IllegalAccessException, IllegalArgumentException { 

    Map<String, String> errors = new HashMap<String, String>(); 

    for (Field field : this.getClass().getDeclaredFields()) { 
     field.setAccessible(true); 
     String value = (String) field.get(this); 

     if (value.equals("N")) { 
      if (!errors.containsKey(field.getName())) { 
       errors.put(field.getName(), value); 
      } 
     } 
    } 
    return errors; 
} 
+0

是代码混淆? – Henry

问题是,要生成代码覆盖率EclEmma会为您的课程添加字段private static final transient boolean[] $jacocoData

由于该字段仅在代码覆盖运行期间存在,所以正常的单元测试通过,但代码覆盖运行失败:您的原始代码不期望这个非字符串字段。

最好的解决办法是检查,如果你看到现场确实是一个字符串字段,否则跳过字段值的测试:

for (Field field : this.getClass().getDeclaredFields()) { 
    field.setAccessible(true); 
    if (field.getType() != String.class) { 
     continue; 
    } 
    String value = (String) field.get(this); 

    if (value.equals("N")) { 
     if (!errors.containsKey(field.getName())) { 
      errors.put(field.getName(), value); 
     } 
    } 
} 

尝试这样做:

String value = "null"; 
if(field.get(this) != null) 
    value = field.get(this).toString(); 

取而代之的是:

String value = (String) field.get(this); 
+2

请注意,如果'field.get(this)'为'null',则可能会失败。最好使用'Objects.toString(field.get(this))'。 –

+0

你很正常,我纠正自己 – NatNgs

+0

@AndyTurner怎么会这样,你总是在那里,正确,还不到30k repu? :) – xenteros

最后,我检查了字段值是String的实例,并将cast转换为String功能toString()

String value = null; 
Object fieldValue = field.get(this); 
if (fieldValue instanceof String) { 
    value = fieldValue.toString(); 
} 

if ("N".equals(value)) { 
    if (!errors.containsKey(field.getName())) { 
     errors.put(field.getName(), value); 
    } 
}