ClassCastException异常的准时造成的错误?
-
19-09-2019 - |
题
鉴于这种片的代码:
public static void writeFile(File file,List buffer)throws IOException{
File fic = new File(file.getCanonicalPath());
cat.debug("writing file : "+fic.getAbsolutePath());
FileOutputStream out = new FileOutputStream(fic);
PrintStream ps = new PrintStream(out);
for(int i=0;i<buffer.size();i++){
ps.println(buffer.get(i));
}
ps.flush();
ps.close();
out.close();
}
(请没有关于如何安全地关闭流的建议,这是遗留代码和新版本使得使用try /最后)
我得到在一个ClassCastException “ps.println(buffer.get(i))的”
此方法被称为几次(比如5次)与列表仅填充有字符串 (说ErrorObject),那么,它被称为与充满字符串和其他对象的列表 在我们到达的第一个ErrorObject点,我们得到的ClassCastException异常。
com.mycompany.ErrorObject incompatible with java.lang.String
在生产环境中,会出现此问题,但是不能在开发环境中再现: PROD:JVM = IBM J9 VM 2.4 J2RE 1.6.0 IBM J9 2.4 AIX PPC-32 jvmap3260-20081105_25433(启用JIT,启用AOT) 开发:WinXP中,JDK 1.6.0_16
有什么理由这个代码可能会失败?
据最近被修补,我担心的制作团队没有正确升级罐子,但我的老板已经检查过该贴片用于correclty ...
我想知道如果刚刚在时间编译器可以代替ps.println(对象)“线”的ps.println到ps.println(字符串)。 这可以解释这样的问题,但我不知道,如果这一切成为可能。
任何建议表示欢迎,感谢你在前进
编辑: 有人问我,完整的堆栈跟踪所以在这里,它是:
java.lang.ClassCastException: com.mycompany.util.ErrorObject incompatible with java.lang.String
at com.mycompany.util.FileUtils.writeFile(FileUtils.java:91)
at com.mycompany.util.FileUtils.writeFile(FileUtils.java:50)
at com.mycompany.itools.task.DBCompareInits.doDBTask(DBCompareInits.java:959)
at com.mycompany.itools.task.DBTask.doTask(DBTask.java:115)
at com.mycompany.itools.task.TaskGroup.startGroup(TaskGroup.java:115)
at com.mycompany.runner.Runner.main(Runner.java:209)
编辑2: javap的-c
65: invokeinterface #20, 1; //InterfaceMethod java/util/List.size:()I
70: if_icmpge 92
73: aload 4
75: aload_1
76: iload 5
78: invokeinterface #21, 2; //InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
83: invokevirtual #31; //Method java/io/PrintStream.println:(Ljava/lang/Object;)V
86: iinc 5, 1
89: goto 62
92: aload 4
94: invokevirtual #32; //Method java/io/PrintStream.flush:()V
97: aload 4
99: invokevirtual #33; //Method java/io/PrintStream.close:()V
102: aload_3
103: invokevirtual #28; //Method java/io/FileOutputStream.close:()V
解决方案
我想知道如果刚刚在时间编译器可以代替ps.println(对象)“线”的ps.println到ps.println(字符串)。这可以解释这样的问题,但我不知道,如果这一切成为可能。
这是不可能的。或者至少不会,除非有一个字节码编译器或JIT编译器错误。你应该只怪编译器错误,如果你有无可辩驳的证据,这是如此。
不过,我会检查的第一件事是,正在执行的代码是真的从你正在寻找的源代码编译。确认这一点的一种方法是从源代码重新编译,然后在类的相应副本运行javap
的结果进行比较。纵观字节码还会告诉你的字节码编译器说要使用的println
的过载。
修改强> - 所述javap
输出清楚地表明,字节码的该版本应该调用println(Object)
,有看不到checkcast
操作码。调用错方法的JIT编译器故障的和自发插入代码做classcast鸣响越来越难以置信。
其他提示
声明toString()方法在ErrorObject类内部转换为字符串,并添加+“”给println()调用。像pintln(errorObjList + “”);