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 :

Méthode à ellipse et argument null


Sujet :

Langage Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juillet 2010
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2010
    Messages : 6
    Par défaut Méthode à ellipse et argument null
    Bonjour à tous,

    Je viens de tomber sur un comportement de Java que je ne m'explique pas. Lorsque qu'on passe l'argument null à une méthode à ellipse on obtient une exception NullPointerException mais si on passe une référence dont la valeur est null tout se passe bien.

    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
     
    public class Test {
        private static void f(Object... objects) {
            System.out.println(objects.length + " arguments");
        }
     
        public static void main(String[] args) {
            Object obj = null;
     
            f(); // fonctionne
            //f(null); // ne fonctionne pas
            f(obj); // fonctionne
            f(null, null); // fonctionne
        }
    }
    Est-ce que quelqu'un sait pourquoi? Non que ce soit une question fondamentale mais j'aimerais comprendre ce qui se passe.

    Cordialement.

  2. #2
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    En réalité,
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    private static void f(Object... objects)
    est compilé comme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    private static void f(Object[] objects)
    si t'as un bon IDE, sur ton appel, tu devrais voir ceci:

    The argument of type null should explicitly be cast to Object[] for the invocation of the varargs method f(Object...) from type Main. It could alternatively be cast to Object for a varargs invocation
    Ce qu'essaie de te dire l'IDE, c'est qu'il y a peut être ambiguité dans le chef du programmeur. Cet appel peut être interprété de deux manières:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    f((Object[])null);
    f((Object)null);
    Le premier étant celui que prendra la JVM en appliquant les règles de la JLS. En conséquence, sur cet appel, objects est null dans f, d'ou ton exception quand tu appelle f.length.

    Il faut être prudent avec les ellipses, particulièrement quand on leur passe un null ou un Object[]. De la même manière, prudence lorsqu'on utilise simultanément l'éllipse et une méthode aux arguments similaires qui utiliser un tableau!
    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
    public class Main {
    	 private static void f(String key, Object... objects) {
    		 System.out.print(key+": ");
    		 if (objects!=null)
    	        System.out.println(objects.length + " argument(s): "+Arrays.deepToString(objects));
    		 else
    			 System.out.println("objects vaut null!");
    	    }
     
    	    public static void main(String[] args) {
    	        Object obj = null;
    	        Object[] tableau = new Object[]{"un","deux"};
     
    	        f("vide"); 
    	        f("object null",obj); 
    	        f("deux nulls",null, null); 
    	        f("tableau",tableau);
    	        f("(Object)tableau",(Object)tableau);
    	        f("null",null); 
    	        f("(Object)null",(Object)null);
    	        f("(Object[])null",(Object[])null);
    	    }
     
    }

  3. #3
    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,


    Et plus généralement, il ne faut jamais ignorer les warnings du compilateur


    a++

  4. #4
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juillet 2010
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2010
    Messages : 6
    Par défaut
    Réponse claire, précise et rapide.

    Merci beaucoup

    PS : effectivement j'avais raté le warning à la compilation

    warning: non-varargs call of varargs method with inexact argument type for last parameter;
    cast to java.lang.Object for a varargs call
    cast to java.lang.Object[] for a non-varargs call and to suppress this warning
    f(null);

  5. #5
    Membre averti

    Homme Profil pro
    Développeur Java
    Inscrit en
    Juillet 2007
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Juillet 2007
    Messages : 26
    Par défaut Et pour le virer le warning ????
    Bonjour à tous,

    Désolé de m'incruster.
    Mais le comportement à ellipse est tout de meme particulier.

    Je créée une classe abstraite de constructeur
    public Constructeur(Objet o1, Objet o2, Object... os){
    super();
    init(os);
    ...
    }
    et de méthode abstraite comme ceci.
    protected abstract init(Object... os);

    Jusque là, pas de problème.

    Dans une de mes classes qui hérite de ma classe abstraite, je souhaite passer dans la liste l'objet "os" au constructeur, un tableau de String.
    super(o1, o2, String[]) et ca me fait :
    The argument of type String[] should explicitly be cast to Object[] for the invocation of the varargs constructor Excel(String, String, Object...). It could alternatively be cast to Object for a varargs invocation

    Comment me débarrasser du warning pour être propre (ca marche sinon pour le moment).

  6. #6
    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
    Citation Envoyé par mclane1 Voir le message
    Mais le comportement à ellipse est tout de meme particulier.
    Certes. Mais bon, dans les cas les plus courants c'est bien pratique.

    Citation Envoyé par mclane1 Voir le message
    The argument of type String[] should explicitly be cast to Object[] for the invocation of the varargs constructor Excel(String, String, Object...). It could alternatively be cast to Object for a varargs invocation

    Comment me débarrasser du warning pour être propre.
    Exactement de la façon indiquée par ce message d'erreur. Figure-toi qu'il ne te ment même pas \o/
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  7. #7
    Membre averti

    Homme Profil pro
    Développeur Java
    Inscrit en
    Juillet 2007
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Juillet 2007
    Messages : 26
    Par défaut
    Pourquoi j'ai l'impression d'être c..
    En effet ca marche ca :
    super(o1, o2, (Object[])os);
    plus de warning...

    Excusez-moi, je sors d'une grippe et tout le monde me dit que j'ai encore l'air pale... Dedans aussi ca doit encore être pale .

Discussions similaires

  1. Argument "NULL" isn't numeric
    Par dva2tlse dans le forum Langage
    Réponses: 4
    Dernier message: 29/11/2009, 19h54
  2. Comment executer une liste de méthodes passées en argument
    Par Mengué georges dans le forum Langage
    Réponses: 11
    Dernier message: 01/10/2007, 17h33
  3. Invoke avec arguments null
    Par Shiftane dans le forum API standards et tierces
    Réponses: 1
    Dernier message: 28/06/2006, 10h51
  4. Méthode retournant deux arguments
    Par Anabel dans le forum Langage
    Réponses: 4
    Dernier message: 30/05/2006, 16h34
  5. Réponses: 3
    Dernier message: 22/05/2006, 21h15

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