سؤال

قرأت بعض المقالات المكتوبة على "ClasscastException"، لكنني لم أستطع الحصول على فكرة جيدة على ذلك. هل هناك مقال جيد أو ما سيكون شرحا موجزا؟

هل كانت مفيدة؟

المحلول

مباشرة من مواصفات API ل ClassCastException:

ألقيت للإشارة إلى أن الرمز حاول إلقاء كائن إلى فئة فرعية منها ليست مثالا.

لذلك، على سبيل المثال، عندما يحاول المرء أن يلقي Integer إلى أ String, String ليست فئة فرعية من Integer, ، لذلك ClassCastException سوف ألقيت.

Object i = Integer.valueOf(42);
String s = (String)i;            // ClassCastException thrown here.

نصائح أخرى

انها حقا بسيطة حقا: إذا كنت تحاول Typecast كائن من الفئة A في كائن من الفئة B، فهي غير متوافقة، تحصل على استثناء من الفصل الدراسي.

دعونا نفكر في مجموعة من الفصول الدراسية.

class A {...}
class B extends A {...}
class C extends A {...}
  1. يمكنك إلقاء أي من هذه الأشياء للاعتراض، لأن جميع فئات Java ترث من الكائن.
  2. يمكنك وضع إما ب أو C إلى A، لأنها كلاهما "أنواع"
  3. يمكنك إلقاء مرجع إلى كائن إلى ب فقط اذا الكائن الحقيقي هو B.
  4. لا يمكنك إلقاء B إلى C على الرغم من أنهم كلاهما.

إنه استثناء يحدث إذا حاولت سجل فئة، ولكن في الواقع فئة ليست من هذا النوع.

النظر في هذه الجيرارشي:

كائن -> الحيوان -> الكلب

قد يكون لديك طريقة تسمى:

 public void manipulate(Object o) {
     Dog d = (Dog) o;
 }

إذا دعا هذا الرمز:

 Animal a = new Animal();
 manipulate(a);

سوف يترجم فقط على ما يرام، ولكن في وقت التشغيل سوف تحصل على ClassCastException لأن o كان في الواقع حيوان، وليس الكلب.

في الإصدارات الأحدث من Java، تحصل على تحذير مترجم إلا إذا قمت بذلك:

 Dog d;
 if(o instanceof Dog) {
     d = (Dog) o;
 } else {
     //what you need to do if not
 }

النظر في مثال،

class Animal {
    public void eat(String str) {
        System.out.println("Eating for grass");
    }
}

class Goat extends Animal {
    public void eat(String str) {
        System.out.println("blank");
    }
}

class Another extends Goat{
  public void eat(String str) {
        System.out.println("another");
  }
}

public class InheritanceSample {
    public static void main(String[] args) {
        Animal a = new Animal();
        Another t5 = (Another) new Goat();
    }
}

في Another t5 = (Another) new Goat(): سوف تحصل على ClassCastException لأنه لا يمكنك إنشاء مثيل Another فئة باستخدام Goat.

ملحوظة: التحويل ساري المفعول فقط في الحالات التي يمتد فيها فئة فئة الوالدين ويتم صب فئة الطفل على فئة الوالدين.

كيفية التعامل مع ClassCastException:

  1. كن حذرا عند محاولة إلقاء كائن من فئة إلى فئة أخرى. تأكد من أن النوع الجديد ينتمي إلى أحد فصوله الأم.
  2. يمكنك منع ClasscastException باستخدام Generics، لأن الأجداد توفر عمليات التحقق من وقت الترجمة ويمكن استخدامها لتطوير تطبيقات آمنة من النوع.

مصدر الملاحظة والباقي

أنت تحاول التعامل مع كائن كمثال من فئة ليست كذلك. إن موظري تقريبا لمحاولة الضغط على دواسة المثبط على الغيتار (البيانو يحتوي على دواسات مثبطات، لا).

هل تفهم مفهوم الصب؟ الصب هو عملية تحويل النوع، وهو في جافا شائع جدا لأن لغةها مكتوبة ثابتة. بعض الأمثلة:

يلقي السلسلة "1" إلى int -> لا مشكلة

يلقي السلسلة "ABC" إلى Int -> يثير كلاسكاستد

أو التفكير في رسم تخطيطي للفئة مع حيوان.Class، dog.class and cat.class

Animal a = new Dog();
Dog d = (Dog) a; // No problem, the type animal can be casted to a dog, because its a dog.
Cat c = (Dog) a; // Raises class cast exception; you can't cast a dog to a cat.

يتم إلقاء استثناء Class Cast بواسطة Java عند محاولة إلقاء كائن من نوع بيانات واحد إلى آخر.

يتيح لنا Java أن يلقي المتغيرات من نوع واحد إلى آخر طالما يحدث الصب بين أنواع البيانات متوافقة.

على سبيل المثال، يمكنك إلقاء سلسلة ككائن ومثل كائن يحتوي على قيم سلسلة يمكن أن يلقي إلى سلسلة.

مثال

دعونا نفترض أن لدينا HASHMAP تحمل عدد من كائنات الصفيف.

إذا كنا نكتب التعليمات البرمجية مثل هذا:

String obj = (String) hmp.get(key);

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

مثال جيد جدا أنني أستطيع أن أعطيك لنظام التشغيل ClasscastException في جافا أثناء استخدام "مجموعة"

List list = new ArrayList();
list.add("Java");
list.add(new Integer(5));

for(Object obj:list) {
    String str = (String)obj;
}

هذا الرمز أعلاه سوف يمنحك ClasscastException في وقت التشغيل. لأنك تحاول إلقاء عدد صحيح على السلسلة، من شأنها أن ترمي الاستثناء.

يمكنك فهم ClasscastException والصب بشكل أفضل بمجرد أن تدرك أن JVM لا يمكن أن تخمن المجهول. إذا كانت B مثال على وجود عدد أكبر من أعضاء فئة وأساليب على كومة من A. لا يمكن ل JVM تخمين كيفية الإدلاء ب B منذ هدف التعيين أكبر، ولن يعرف JVM كيفية ملء الأعضاء الإضافيين.

ولكن إذا كان مثالا من B، فسيكون ذلك ممكنا، لأن A مرجعا على مثيل كامل ب، وبالتالي فإن التعيين سيكون واحدا إلى واحد.

يعد Java ClasscastException استثناء يمكن أن يحدث عند محاولة تحويل فئة واحدة بشكل غير صحيح من نوع إلى آخر.

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class ClassCastExceptionExample {

  public ClassCastExceptionExample() {

    List list = new ArrayList();
    list.add("one");
    list.add("two");
    Iterator it = list.iterator();
    while (it.hasNext()) {
        // intentionally throw a ClassCastException by trying to cast a String to an
        // Integer (technically this is casting an Object to an Integer, where the Object 
        // is really a reference to a String:
        Integer i = (Integer)it.next();
    }
  }
 public static void main(String[] args) {
  new ClassCastExceptionExample();
 }
}

إذا حاولت تشغيل برنامج Java هذا سترى أنه سيقوم برمي ClasscastException:

Exception in thread "main" java.lang.ClassCastException: java.lang.String
at ClassCastExceptionExample  (ClassCastExceptionExample.java:15)
at ClassCastExceptionExample.main  (ClassCastExceptionExample.java:19)

السبب في إلقاء الاستثناء هنا هو أنه عندما أقوم بإنشاء كائن قائمتي، فإن الكائن الذي أقوم بتخزينه في القائمة هو السلسلة "ONE"، ولكن بعد ذلك، لاحقا عندما أحاول الحصول على هذا الكائن، ارتكب خطأ عن قصد من خلال المحاولة لإلقاء ذلك على عدد صحيح. نظرا لأن سلسلة لا يمكن أن تؤدي مباشرة إلى عدد صحيح - عددا صحيحا ليس نوعا من السلسلة - يتم إلقاء الفئة Classcaste.

إذا كنت ترغب في فرز الكائنات ولكن إذا لم تنفذ الطبقة قابلة للمقارنة أو المقارنة، فستحصل على الفصل الدراسي على سبيل المثال

class Animal{
   int age;
   String type;

   public Animal(int age, String type){
      this.age = age;
      this.type = type;
   }
}
public class MainCls{
   public static void main(String[] args){
       Animal[] arr = {new Animal(2, "Her"), new Animal(3,"Car")};
       Arrays.sort(arr);
   }
}

الطريقة الرئيسية أعلاه سوف ترمي استثناء من فئة وقت التشغيل

استثناء في موضوع "Main" java.lang.lang.classcastexception: com.default.animal لا يمكن أن يلقي إلى java.lang.comparable

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