110 votes

Vous appelez la méthode Java varargs avec un seul argument null?

Si j'ai une méthode Java vararg foo(Object ...arg) et que j'appelle foo(null, null) , j'ai les deux arg[0] et arg[1] as null s. Mais si j'appelle foo(null) , arg est nul. Pourquoi cela arrive-t-il?

Comment appeler foo que foo.length == 1 && foo[0] == null soit true ?

103voto

Mike Deck Points 7443

Le problème est que, lorsque vous utilisez le littéral null, Java ne sait pas quel type il est censé être. Il peut s'agir d'un objet null ou d'un tableau d'objet null. Pour un seul argument, il suppose le dernier.

Vous avez deux choix. Convertissez explicitement la valeur null en Object ou appelez la méthode à l'aide d'une variable fortement typée. Voir l'exemple ci-dessous:

 public class Temp{
   public static void main(String[] args){
      foo("a", "b", "c");
      foo(null, null);
      foo((Object)null);
      Object bar = null;
      foo(bar);
   }

   private static void foo(Object...args) {
      System.out.println("foo called, args: " + asList(args));
   }
}
 

Sortie:

 foo called, args: [a, b, c]
foo called, args: [null, null]
foo called, args: [null]
foo called, args: [null]
 

29voto

Bozho Points 273663

Vous avez besoin d'une distribution explicite sur Object :

 foo((Object) null);
 

Sinon, l'argument est supposé être l'ensemble du tableau représenté par varargs.

7voto

David Tonhofer Points 1816

Un Cas de Test pour l'illustrer:

Le code Java avec un vararg la prise de déclaration de méthode (statique):

public class JavaReceiver {
    public static String receive(String... x) {
        String res = ((x == null) ? "null" : ("an array of size " + x.length));
        return "received 'x' is " + res;
    }
}

Ce code Java (un JUnit4 cas de test) appelle le ci-dessus (nous utilisons le test de ne pas tester n'importe quoi, juste pour générer de la puissance de sortie):

import org.junit.Test;

public class JavaSender {

    @Test
    public void sendNothing() {
        System.out.println("sendNothing(): " + JavaReceiver.receive());
    }

    @Test
    public void sendNullWithNoCast() {
        System.out.println("sendNullWithNoCast(): " + JavaReceiver.receive(null));
    }

    @Test
    public void sendNullWithCastToString() {
        System.out.println("sendNullWithCastToString(): " + JavaReceiver.receive((String)null));
    }

    @Test
    public void sendNullWithCastToArray() {
        System.out.println("sendNullWithCastToArray(): " + JavaReceiver.receive((String[])null));
    }

    @Test
    public void sendOneValue() {
        System.out.println("sendOneValue(): " + JavaReceiver.receive("a"));
    }

    @Test
    public void sendThreeValues() {
        System.out.println("sendThreeValues(): " + JavaReceiver.receive("a", "b", "c"));
    }

    @Test
    public void sendArray() {
        System.out.println("sendArray(): " + JavaReceiver.receive(new String[]{"a", "b", "c"}));
    }
}

L'exécution de cette comme un test Unitaire, on obtient:

sendNothing(): a reçu un 'x' est un tableau de taille 0
sendNullWithNoCast(): a reçu un 'x' est null
sendNullWithCastToString(): a reçu un 'x' est un tableau de taille 1
sendNullWithCastToArray(): a reçu un 'x' est null
sendOneValue(): a reçu un 'x' est un tableau de taille 1
sendThreeValues(): a reçu un 'x' est un tableau de taille 3
sendArray(): a reçu un 'x' est un tableau de taille 3

Afin de rendre cela plus intéressant, nous allons l'appeler l' receive() fonction de Groovy 2.1.2 et voir ce qui se passe. Il s'avère que les résultats ne sont pas les mêmes! Cela peut être un bug.

import org.junit.Test

class GroovySender {

    @Test
    void sendNothing() {
        System.out << "sendNothing(): " << JavaReceiver.receive() << "\n"
    }

    @Test
    void sendNullWithNoCast() {
        System.out << "sendNullWithNoCast(): " << JavaReceiver.receive(null) << "\n"
    }

    @Test
    void sendNullWithCastToString() {
        System.out << "sendNullWithCastToString(): " << JavaReceiver.receive((String)null) << "\n"
    }

    @Test
    void sendNullWithCastToArray() {
        System.out << "sendNullWithCastToArray(): " << JavaReceiver.receive((String[])null) << "\n"
    }

    @Test
    void sendOneValue() {
        System.out << "sendOneValue(): " + JavaReceiver.receive("a") << "\n"
    }

    @Test
    void sendThreeValues() {
        System.out << "sendThreeValues(): " + JavaReceiver.receive("a", "b", "c") << "\n"
    }

    @Test
    void sendArray() {
        System.out << "sendArray(): " + JavaReceiver.receive( ["a", "b", "c"] as String[] ) << "\n"
    }

}

L'exécution de cette comme un test JUnit rendements suivants, à la différence de Java en caractères gras.

sendNothing(): a reçu un 'x' est un tableau de taille 0
sendNullWithNoCast(): a reçu un 'x' est null
sendNullWithCastToString(): a reçu un 'x' est null
sendNullWithCastToArray(): a reçu un 'x' est null
sendOneValue(): a reçu un 'x' est un tableau de taille 1
sendThreeValues(): a reçu un 'x' est un tableau de taille 3
sendArray(): a reçu un 'x' est un tableau de taille 3

3voto

Buhake Sindi Points 38654

Vous devez comprendre ce que les varargs . Les varargs méthode prend un nombre arbitraire de valeurs et met la valeur dans un tableau avant la méthode est invoquée.

si vous n' foo(null); il est traduit comme foo(Object[] arg) depuis 1 valeur est passée. Depuis sa 1 seule valeur de paramètre transmise, elle est librement interprétée comme Object[] args = null et c'est pourquoi args est - null dans votre cas.

foo(null, null) crée potentiellement un Object[] argarg[0] = arg[1] = null;

Espérons que cette aide.

3voto

ColinD Points 48573

En effet, une méthode varargs peut être appelée avec un tableau réel plutôt qu’une série d’éléments de tableau. Lorsque vous lui communiquez le null ambigu ambigu, il suppose que null est un Object[] . L'utilisation de null à Object résoudra ce problème.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X