Java Language Rétrécissement et élargissement des références d'objet


Exemple

Lancer une instance d'une classe de base dans une sous-classe comme dans: b = (B) a; est appelé rétrécissement (car vous essayez de restreindre l'objet de classe de base à un objet de classe plus spécifique) et nécessite un transtypage explicite.

Convertir une instance d'une sous-classe en une classe de base comme dans: A a = b; est appelé l' élargissement et n'a pas besoin d'une conversion de type.

Pour illustrer, considérons les déclarations de classe suivantes et le code de test:

class Vehicle {
}

class Car extends Vehicle {
}

class Truck extends Vehicle {
}

class MotorCycle extends Vehicle {
}

class Test {

    public static void main(String[] args) {
    
        Vehicle vehicle = new Car();
        Car car = new Car();        
    
        vehicle = car; // is valid, no cast needed

        Car c = vehicle // not valid
        Car c = (Car) vehicle; //valid
    }
}

La déclaration Vehicle vehicle = new Car(); est une instruction Java valide. Chaque instance de Car est également un Vehicle . Par conséquent, l'affectation est légale sans nécessiter un transtypage explicite.

Par contre, Car c = vehicle; n'est pas valide. Le type statique de la variable vehicle est Vehicle ce qui signifie qu’il peut se référer à une instance de Car , Camion , MotorCycle , or any other current or future subclass of Véhicule . (Or indeed, an instance of Vehicle itself, since we did not declare it as an class.) The assignment cannot be allowed, since that might lead to abstraite class.) The assignment cannot be allowed, since that might lead to voiture à se referring to a instance de Truck`.

Pour éviter cette situation, nous devons ajouter un type-cast explicite:

Car c = (Car) vehicle;

Le type-cast indique au compilateur que nous nous attendons à la valeur du vehicle soit une Car ou une sous - classe de Car . Si nécessaire, le compilateur insérera du code pour effectuer une vérification du type à l'exécution. Si la vérification échoue, une ClassCastException sera lancée lorsque le code est exécuté.

Notez que tous les types ne sont pas valides. Par exemple:

String s = (String) vehicle;  // not valid

Le compilateur Java sait que une instance qui est de type compatible avec Vehicle ne peut jamais être de type compatible avec String . Le cast de type n'a jamais pu réussir, et le JLS impose une erreur de compilation.