代码之家  ›  专栏  ›  技术社区  ›  chburd

类CastException是由Bug及时引起的吗?

  •  2
  • chburd  · 技术社区  · 15 年前

    给出这段代码:

    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/finally)

    我在“ps.println(buffer.get(i))处得到一个ClassCastException

    这个方法被调用了好几次(比如说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_(启用jit,启用aot) 开发:winxp,jdk 1.6.0_16

    这段代码可能失败有什么原因吗?

    它是最近修补的,我担心生产团队没有正确升级罐子,但我的老板已经检查了修补程序是否正确应用…

    我想知道即时编译器是否可以将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
    
    2 回复  |  直到 15 年前
        1
  •  4
  •   Stephen C    15 年前

    我想知道即时编译器是否可以将ps.println“连接”到ps.println(字符串)而不是ps.println(对象)。这可以解释这个问题,但我不知道这是否可能。

    这是不可能的。或者至少没有,除非存在字节码编译器或jit编译器错误。如果你有确凿的证据证明是这样的话,你就应该责怪编译器错误。

    不过,我要检查的第一件事是,执行的代码实际上是从您正在查看的源代码编译的。确认这一点的一种方法是从源代码重新编译,然后比较运行的结果 javap 在班级的副本上。查看字节码也会告诉您 println 字节码编译器说要使用。

    编辑 - JAVAP 输出清楚地显示字节码的版本应该调用 println(Object) ,而且没有 checkcast 操作码在眼前。调用错误方法的jit编译器错误 自发地插入代码来进行类转换听起来越来越不可信。

        2
  •  0
  •   Artsiom Anisimau    15 年前

    在errorobject类中声明to string()方法,并在println()调用中添加“+”。像pintln(errorobjlist+“”);