IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage Java Discussion :

Type safety & Generic


Sujet :

Langage Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre très actif
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Mai 2014
    Messages
    227
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2014
    Messages : 227
    Par défaut Type safety & Generic
    Bonjour tout le monde, je viens vers vous aujourd'hui pour un problème de typage. J'ai une classe générique qui hérite d'une interface générique elle aussi. Je souhaite ajouter à cette classe l'interface Cloneable mais je rencontre un problème de sécurité. Je comprends le problème mais je ne sais pas comment le résoudre.

    La classe en question :
    Vector2
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
     
    package fr.lurya.math;
     
    public abstract class Vector2<T extends Number> implements VectorPrimal<T>, Cloneable {
     
    	public Vector2() {
    		super();
    	}
     
    	public Vector2( T x, T y) {
    		this.x = x;
    	}
     
    	public Object clone() {
    		Vector2<T> vector = null;
    		try {
    			vector = (Vector2<T>) super.clone();
    		} catch(CloneNotSupportedException e) {
    	      	e.printStackTrace(System.err);
    	    }
    		return vector;
    	}
     
     
    	private T x;
    	private T y;
     
    	private static final long serialVersionUID = -7497528690951749972L;
    }
    Le problème vient de cette ligne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    vector = (Vector2<T>) super.clone();
    //Type safety: Unchecked cast from Object to Vector2<T>
    Merci de votre aide

  2. #2
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 582
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 582
    Par défaut
    Hello,

    en pratique il n'y a pas de problème de sécurité. Le système de clonage fourni par la superclasse, Object, fonctionne en créant une nouvelle instance de la classe en cours, et en affectant à chaque champ de cette instance, la même valeur que l'instance clonée. L'effet donc, est que les champs de type générique, x et y, se retrouvent à pointer vers les mêmes objets que ce soit dans l'instance de départ et dans l'instance clonée. L'instance de départ et l'instance clonée ayant donc le même contenu, elles ont les mêmes causes donc les mêmes effets, et puisque l'instance de départ est safe de type Vector2<T>, alors l'instance clonée l'est aussi. Aucun problème de type safety en pratique.

    En pratique. Mais en théorie le compilateur ne peut pas savoir tout le raisonnement de sûreté que je viens de tenir au-dessus. Toutes ces considérations outrepassent largement son rôle.

    C'est toi et moi qui savons que le type safety est respecté, parce que nous savons que l'Object qui est cast en Vector2<T> est issu du clonage via Object.clone() d'un objet qui respecte déjà ce type safety. Que des choses qui passent bien au-dessus d'un simple compilateur. Ce sont nous les humains qui savent que c'est bon. Pas le compilateur qui est chargé de le vérifier automatiquement.

    Dans ce cas-là, la bonne conduite est d'écrire une documentation claire en commentaire, de comment tu sais que le type safety est respecté grâce aux mesures que tu as mises en œuvre et que le compilateur ne pouvait pas connaître. Puis de mettre un @SuppressWarnings("unchecked")
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  3. #3
    Membre très actif
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Mai 2014
    Messages
    227
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2014
    Messages : 227
    Par défaut
    Je te remercie pour cette réponse claire et précise, je vais de ce pas documenté tout ça

    Bonne soirée

  4. #4
    Expert éminent
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Billets dans le blog
    1
    Par défaut
    Salut,


    Deux petites remarques sur ton code.

    • Tu retrouveras le problème de type-safety lorsque tu utilises la méthode clone() de ton objet, puisque celle-ci déclare retourner un Object.
      Tu peux utiliser la covariance pour changer le type de retour, et ainsi lui donner le type réel.
    • Ta gestion des exceptions n'est pas tip-top.
      Alors ok la CloneNotSupportedException ne devrait jamais arriver puisque tu implémentes Cloneable, mais si par malheur tu oublie cela un jour et que l'exception remonte tu vas te contenter de logger dans la console et de retourner null... ce qui va engendrer une autre erreur, éventuellement bien plus loin dans le code, et donc plus difficile à déceler.
      Il est préférable de remonter directement une exception "unchecked" (pour ne pas avoir à la traiter tout le temps).



    Bref ta méthode clone() devrait plutôt ressembler à cela :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    	@Override
    	public Vector2<T> clone() {
    		try {
    			@SuppressWarnings("unchecked")
    			final Vector2<T> vector  = (Vector2<T>) super.clone();
     
    			// clone recursif si besoin
     
    			return vector;
    		} catch(CloneNotSupportedException e) {
    	      	throw new IllegalStateException(e);
    	    }
    	}

    a++

  5. #5
    Membre très actif
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Mai 2014
    Messages
    227
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2014
    Messages : 227
    Par défaut
    Je te remercie, c'est ce que j'ai fais, le code ci-dessus n'était pas terminé

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Warning "ArrayList is a raw type. References to generic type ArrayList<E>
    Par sandrine49 dans le forum Collection et Stream
    Réponses: 2
    Dernier message: 10/08/2008, 10h48
  2. warning Type safety
    Par anasshb dans le forum Langage
    Réponses: 3
    Dernier message: 01/10/2007, 18h15
  3. [c#][Reflexion] Obtenir le type d'un generic
    Par shwin dans le forum Windows Forms
    Réponses: 12
    Dernier message: 03/08/2006, 16h34
  4. Un type safety
    Par arsenik7 dans le forum Langage
    Réponses: 3
    Dernier message: 30/06/2006, 15h55
  5. [Comparator] Warning Type safety
    Par Pollux dans le forum Collection et Stream
    Réponses: 4
    Dernier message: 30/01/2006, 20h43

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo