Downcasting en Java

voix
151

Est autorisée dans transtypage ascendant Java, mais downcasting donne une erreur de compilation.

L'erreur de compilation peut être supprimé en ajoutant un casting mais briserait de toute façon à l'exécution.

Dans ce cas , pourquoi Java permet downcasting si elle ne peut pas être exécuté à l'exécution?
Y at - il pratique pour ce concept?

public class demo {
  public static void main(String a[]) {
      B b = (B) new A(); // compiles with the cast, 
                         // but runtime exception - java.lang.ClassCastException
  }
}

class A {
  public void draw() {
    System.out.println(1);
  }

  public void draw1() {
    System.out.println(2);
  }
}

class B extends A {
  public void draw() {
    System.out.println(3);
  }
  public void draw2() {
    System.out.println(4);
  }
}
Créé 19/12/2008 à 13:11
source utilisateur
Dans d'autres langues...                            


11 réponses

voix
262

Downcasting est permis quand il y a une possibilité que cela au moment de proprement déroulée course:

Object o = getSomeObject(),
String s = (String) o; // this is allowed because o could reference a String

Dans certains cas, cela ne réussira pas:

Object o = new Object();
String s = (String) o; // this will fail at runtime, because o doesn't reference a String

Dans d'autres, il fonctionnera:

Object o = "a String";
String s = (String) o; // this will work, since o references a String

Notez que certains moulages seront refusés au moment de la compilation, parce qu'ils ne réussiront jamais à tous:

Integer i = getSomeInteger();
String s = (String) i; // the compiler will not allow this, since i can never reference a String.
Créé 19/12/2008 à 13:20
source utilisateur

voix
14

Je crois que cela s'applique à toutes les langues statiquement typés:

String s = "some string";
Object o = s; // ok
String x = o; // gives compile-time error, o is not neccessarily a string
String x = (String)o; // ok compile-time, but might give a runtime exception if o is not infact a String

Le typecast dit effectivement: supposons que c'est une référence à la classe de fonte et l' utiliser comme tel. Maintenant, permet de dire o est vraiment un entier, en supposant que cela est une chaîne n'a pas de sens et donnera des résultats inattendus, donc il doit y avoir un contrôle d'exécution et une exception pour notifier l'environnement d'exécution que quelque chose ne va pas.

En pratique, vous pouvez écrire le code de travail sur une classe plus générale, mais le jeter à une sous-classe si vous savez ce que sous-classe, il est et la nécessité de le traiter comme tel. Un exemple typique est prépondérant Object.equals (). Supposons que nous avons une classe pour voiture:

@Override
boolean equals(Object o) {
    if(!(o instanceof Car)) return false;
    Car other = (Car)o;
    // compare this to other and return
}
Créé 19/12/2008 à 13:21
source utilisateur

voix
16

En utilisant votre exemple, vous pouvez faire:

public void doit(A a) {
    if(a instanceof B) {
        // needs to cast to B to access draw2 which isn't present in A
        // note that this is probably not a good OO-design, but that would
        // be out-of-scope for this discussion :)
        ((B)a).draw2();
    }
    a.draw();
}
Créé 19/12/2008 à 14:08
source utilisateur

voix
2

Dans ce cas, pourquoi Java permet downcasting si elle ne peut pas être exécuté à l'exécution?

Je crois que c'est parce qu'il n'y a aucun moyen pour le compilateur de savoir à la compilation si la distribution réussira ou non. Pour exemple, il est facile de voir que la distribution échouera, mais il y a d'autres moments où il n'est pas si clair.

Par exemple, imaginons que les types B, C et D étendent tous type A, puis un procédé public A getSomeA()retourne une instance de chaque B, C ou D en fonction d'un nombre généré de façon aléatoire. Le compilateur ne peut pas savoir quel type exact d'exécution sera retourné par cette méthode, donc si vous lancez plus tard , les résultats B, il n'y a aucun moyen de savoir si la distribution réussira (ou l' échec). Par conséquent , le compilateur doit assumer des moulages réussiront.

Créé 19/12/2008 à 15:17
source utilisateur

voix
5

Nous pouvons tous voir que le code que vous avez fourni ne fonctionnera pas au moment de l' exécution. En effet , nous savons que l'expression new A()peut jamais être un objet de type B.

Mais ce n'est pas comment le compilateur voit. Au moment où le compilateur vérifie si la distribution est autorisée, il voit ceci:

variable_of_type_B = (B)expression_of_type_A;

Et comme d' autres l' ont démontré, ce genre de casting est parfaitement légal. L'expression à droite pourrait très bien évaluer un objet de type B. Le compilateur voit que Aet Bavoir une relation de sous - type, donc avec la vue « expression » du code, le casting pourrait fonctionner.

Le compilateur ne considère pas le cas particulier quand il sait exactement ce type d' objet expression_of_type_Aaura vraiment. Il voit juste le type statique Aet considère le type dynamique pourrait être Aou tout descendant de A, y compris B.

Créé 19/12/2008 à 16:41
source utilisateur

voix
2

@ Affiche originale - voir commentaires en ligne.

public class demo 
{
    public static void main(String a[]) 
    {
        B b = (B) new A(); // compiles with the cast, but runtime exception - java.lang.ClassCastException 
        //- A subclass variable cannot hold a reference to a superclass  variable. so, the above statement will not work.

        //For downcast, what you need is a superclass ref containing a subclass object.
        A superClassRef = new B();//just for the sake of illustration
        B subClassRef = (B)superClassRef; // Valid downcast. 
    }
}

class A 
{
    public void draw() 
    {
        System.out.println("1");
    }

    public void draw1() 
    {
        System.out.println("2");
    }
}

class B extends A 
{
    public void draw() 
    {
        System.out.println("3");
    }

    public void draw2() 
    {
        System.out.println("4");
    }
}
Créé 16/03/2010 à 12:25
source utilisateur

voix
1

Abattu fonctionne dans le cas où nous avons affaire à un objet upcasted. Transtypage ascendant:

int intValue = 10;
Object objValue = (Object) intvalue;

Alors maintenant , cette objValuevariable peut toujours être à downcasted intparce que l'objet qui a été jeté est un Integer,

int oldIntValue = (Integer) objValue;
// can be done 

mais parce objValueest un objet , il ne peut pas être jeté à Stringcause intne peut être jeté à String.

Créé 01/07/2013 à 07:11
source utilisateur

voix
0

Downcasting est très utile dans l'extrait de code suivant, je l'utilise tout le temps. Ainsi, prouvant que downcasting est utile.

private static String printAll(LinkedList c)
{
    Object arr[]=c.toArray();
    String list_string="";
    for(int i=0;i<c.size();i++)
    {
        String mn=(String)arr[i];
        list_string+=(mn);
    }
    return list_string;
}

Je stocke chaîne dans la liste chaînée. Lorsque je récupère les éléments de liste chaînée, les objets sont retournés. Pour accéder aux éléments comme des chaînes (ou tout autre objet de classe), downcasting me aide.

Java nous permet de compiler du code baissés nous faire confiance que nous faisons quelque chose de mal. Pourtant, si les humains font une erreur, il est pris lors de l'exécution.

Créé 13/10/2013 à 05:57
source utilisateur

voix
0

Prenons l'exemple ci-dessous

public class ClastingDemo {

/**
 * @param args
 */
public static void main(String[] args) {
    AOne obj = new Bone();
    ((Bone) obj).method2();
}
}

class AOne {
public void method1() {
    System.out.println("this is superclass");
}
}


 class Bone extends AOne {

public void method2() {
    System.out.println("this is subclass");
}
}

Ici, nous créons l'objet de la sous-classe des os et lui a attribué à la référence super-classe AONE et maintenant référence superclasse ne connaît pas la méthode method2 dans la sous-classe-à-dire des os lors de la compilation time.therefore nous devons downcaster cette référence de superclasse à sous-classe référence de façon la référence résultante peut connaître la présence de méthodes dans la sous-classe-à-dire des os

Créé 08/06/2014 à 05:59
source utilisateur

voix
0

Downcasting transformation d'objets est impossible. Seulement "DownCasting1 _downCasting1 = (DownCasting1) ((DownCasting2) downCasting1);" est posible

class DownCasting0 {
    public int qwe() {
        System.out.println("DownCasting0");
        return -0;
    }
}

class DownCasting1 extends DownCasting0 {
    public int qwe1() {
        System.out.println("DownCasting1");
        return -1;
    }
}

class DownCasting2 extends DownCasting1 {
    public int qwe2() {
        System.out.println("DownCasting2");
        return -2;
    }
}

public class DownCasting {

    public static void main(String[] args) {

        try {
            DownCasting0 downCasting0 = new DownCasting0();
            DownCasting1 downCasting1 = new DownCasting1();
            DownCasting2 downCasting2 = new DownCasting2();

            DownCasting0 a1 = (DownCasting0) downCasting2;
            a1.qwe(); //good

            System.out.println(downCasting0 instanceof  DownCasting2);  //false
            System.out.println(downCasting1 instanceof  DownCasting2);  //false
            System.out.println(downCasting0 instanceof  DownCasting1);  //false

            DownCasting2 _downCasting1= (DownCasting2)downCasting1;     //good
            DownCasting1 __downCasting1 = (DownCasting1)_downCasting1;  //good
            DownCasting2 a3 = (DownCasting2) downCasting0; // java.lang.ClassCastException

            if(downCasting0 instanceof  DownCasting2){ //false
                DownCasting2 a2 = (DownCasting2) downCasting0;
                a2.qwe(); //error
            }

            byte b1 = 127;
            short b2 =32_767;
            int b3 = 2_147_483_647;
//          long _b4 = 9_223_372_036_854_775_807; //int large number max 2_147_483_647
            long b4 = 9_223_372_036_854_775_807L;
//          float _b5 = 3.4e+038; //double default
            float b5 = 3.4e+038F; //Sufficient for storing 6 to 7 decimal digits
            double b6 = 1.7e+038;
            double b7 = 1.7e+038D; //Sufficient for storing 15 decimal digits

            long c1 = b3;
            int c2 = (int)b4;

            //int       4 bytes     Stores whole numbers from -2_147_483_648 to 2_147_483_647
            //float     4 bytes     Stores fractional numbers from 3.4e−038 to 3.4e+038. Sufficient for storing 6 to 7 decimal digits
            float c3 = b3; //logic error
            double c4 = b4; //logic error


        } catch (Throwable e) {
            e.printStackTrace();
        }
    }

}
Créé 30/07/2019 à 12:24
source utilisateur

voix
0

Pour ce faire downcasting en Java, et éviter des exceptions d'exécution, prendre une référence du code ci-dessous:

if (animal instanceof Dog) {
  Dog dogObject = (Dog) animal;
}

Ici, les animaux est la classe mère et le chien est la classe des enfants.
instanceof est un mot - clé qui est utilisé pour vérifier si une variable de référence est un type donné contenant de référence d'objet ou non.

Créé 06/09/2019 à 13:59
source utilisateur

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more