ClasscastException الناجم عن الأخطاء في الوقت المناسب؟

StackOverflow https://stackoverflow.com/questions/2425487

  •  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();
}

(يرجى عدم وجود نصيحة حول كيفية إغلاق التدفقات بأمان، وهذا هو الرمز القديم والإصدار الجديد يستفيد من محاولة / أخيرا)

أحصل على ClasscastException في "ps.println (buffer.get (i))"

وتسمى هذه الطريقة عدة مرات (قل 5 مرات) مع قائمة مليئة فقط بأسلوتات إذن، يتم استدعاؤها بقائمة مليئة بالسلسلة وكائن آخر (Say ErrorObject) عند نقطة نصل إلى 1st ErrorObject، نحصل على ClasscastException وبعد

com.mycompany.ErrorObject incompatible with java.lang.String

تحدث هذه المشكلة في بيئة الإنتاج، ولكن لا يمكن استنساخها في بيئة DEV: Prod: JVM = IBM J9 VM 2.4 J2RE 1.6.0 IBM J9 2.4 AIX PPC-32 JVMAP3260-20081105_25433 (JIT تم تمكينه، Aot تمكين) Dev: WinXP، JDK 1.6 .0_16.

هل هناك أي سبب يمكن أن يفشل هذا الرمز؟

تم تصحيحه مؤخرا، أخشى أن يقوم فريق الإنتاج بترقية الجرة بشكل صحيح، لكن مدربي فحص بالفعل أن التصحيح تم تطبيقه Correclty ...

كنت أتساءل عما إذا كان برنامج التحويل البرمجي الزمني فقط يمكن أن "سلك" ps.println إلى ps.println (string) بدلا من 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 (string) بدلا من ps.println (كائن). يمكن أن يفسر مثل هذه المشكلة، لكن ليس لدي أي فكرة إذا كان ذلك ممكنا.

ليس من الممكن. أو على الأقل ليس فقط ما لم يكن هناك مترجم bytecode أو خطأ محمول JIT. ويجب عليك إلقاء اللوم على البق المترجم فقط إذا كان لديك أدلة لا رجعة فيها على أن هذا هو كذلك.

ومع ذلك، فإن أول شيء أتحقق منه هو أن الكود الذي يتم تنفيذه تم جمعه حقا من التعليمات البرمجية المصدر التي تنظر إليها. طريقة واحدة لتأكيد ذلك سيكون لإعادة ترجمة المصدر، ثم قارن نتائج التشغيل javap على نسخ المعنية من الفصل. لن يخبرك بالنظر إلى Bytecodes أيضا إلى الحمل الزائد println مترجم bytecode يقول للاستخدام.

تعديل - ال javap يوضح الإخراج بوضوح أن هذا الإصدار من ByTecode يجب أن يسميه println(Object), ، وليس هناك checkcast Opcode في الأفق. خطأ محمول JIT الذي يستدعي الطريقة الخطأ و إدراج رمز تلقائيا للقيام بذكاء يكون سبر أكثر وأكثر من اللازم.

نصائح أخرى

تعلن طريقة ToString () مع تحويل إلى سلسلة داخل في فئة ErrorObject وإضافة + "" "إلى Println (). مثل pintln (errorobjlist + "")؛

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top