100 votes

Java generics types void/Void

Je mets en œuvre un ResponseHandler pour le paquet apache HttpClient, comme ceci :

new ResponseHandler<int>() {
    public int handleResponse(...) {
        // ... code ...
        return 0;
    }
}

mais j'aimerais que le handleResponse pour ne rien retourner, c'est-à-dire void . Est-ce possible ? Ce qui suit ne compile pas, car void n'est pas un type Java valide :

new ResponseHandler<void>() {
        public void handleResponse(...) {
            // ... code ...
        }
}

Je suppose que je pourrais remplacer void con Void pour renvoyer un Void mais ce n'est pas vraiment ce que je veux. Question il est possible d'organiser cette situation de rappel de telle sorte que je puisse renvoyer void de handleResponse ?

111voto

ILMTitan Points 5095

El Void a été créé pour cette situation exacte : pour créer une méthode avec un type de retour générique dont le sous-type peut être "void". Void a été conçu de manière à ce qu'aucun objet de ce type ne puisse être créé. Ainsi, une méthode de type Void retournera toujours null (ou complète anormalement), ce qui est aussi proche du néant que possible. Vous devez mettre return null dans la méthode, mais cela ne devrait être qu'un inconvénient mineur.

En bref : n'utilisez pas Void .

3 votes

Arrgh - la douleur des génériques le problème est que si vous définissez un type de retour de "Void" vous devez mettre un "return(null) ;" la raison principale de déclarer le type de retour de void est que vous n'avez pas à avoir une déclaration de retour, et peut utiliser une méthode existante "void" :) Une partie du problème avec les génériques Java est l'amalgame entre la vérification des types au moment de l'exécution et la nécessité de générer du code au moment de la compilation et de fournir une assistance à la "tenue de livres". On a besoin de "macros" et de "templates" qui facilitent l'écriture du code au moment de la compilation. langue côté.

6 votes

+1 Pour clarifier, Void existe depuis le JDK1.1. Il a été créé à l'origine pour être utilisé avec Reflection mais a un rôle similaire dans les génériques.

0 votes

@ILMTitan Pourriez-vous donner des références à la documentation sur la déclaration "return null" dans les méthodes qui sont définies pour retourner Void ?

75voto

Peter Lawrey Points 229686

Generics ne gère que les classes d'objets. Les types void et primitifs ne sont pas supportés par Generics et vous ne pouvez pas les utiliser comme type paramétré. Vous devez utiliser Void à la place.

Pouvez-vous dire pourquoi vous ne voulez pas utiliser Void ?

11 votes

Je préférerais simplement ne pas avoir à inclure une return dans une fonction où je ne renvoie rien, surtout par souci de propreté.

10 votes

Vous pourriez créer un wrapper abstrait qui vous appelle void et renvoie la méthode null pour cacher cette laideur.

55 votes

+1 pour m'avoir rappelé que "tout problème en informatique peut être résolu en ajoutant une couche d'indirection".

1voto

Tnem Points 3471

Vous ne pouvez pas avoir de primitives dans les génériques de sorte que int est en fait un Integer . L'objet Void est analogue au mot-clé void pour les génériques.

7 votes

void n'est pas une primitive, c'est simplement un mot-clé java. Il n'a pas de "type".

1 votes

Et ce n'est sûrement pas un synonyme ! void (minuscule) - mot-clé, rien n'est renvoyé ; Void (majuscule) - un (infréquentable) classe Une instance de cette classe est renvoyée (elle ne peut être qu'une instance de la classe en question). null car non démontrable)

0 votes

@Carlos Heuberger analogous any better for you ?

0voto

Jon Points 1

Cette implémentation de java.lang.Void en Java parle d'elle-même. Par ailleurs, j'ai écrit un article qui fait le lien avec les génériques. Il m'a fallu un peu de réflexion avant de commencer à comprendre : http://www.siteconsortium.com/h/D00006.php . Avis TYPE = Class.getPrimitiveClass("void") ;

paquet java.lang ;

public final class Void {

    public static final Class<Void> TYPE = Class.getPrimitiveClass("void");

    private Void() {}
}

-1voto

Adrian Smith Points 6087

Hélas, ce n'est pas possible. Vous pouvez configurer le code pour qu'il renvoie Void comme vous le dites, cependant vous ne pouvez jamais instancier un Void Il est donc impossible d'écrire une fonction conforme à cette spécification.

Pensez-y comme ça : La fonction générique dit "cette fonction retourne quelque chose, de type X", et vous pouvez spécifier X mais vous ne pouvez pas changer la phrase en "cette fonction ne retourne rien". (Je ne suis pas sûr d'être d'accord avec cette sémantique, mais c'est comme ça).

Dans ce cas, ce que je fais toujours, c'est de faire en sorte que le type de retour de la fonction soit Object et, en fait, renvoient toujours null .

2 votes

Parce qu'avec un type de retour Object, le compilateur ne peut pas garantir que seul null est retourné. En développant la réponse de Thomas, essayez ceci : static Void v() { return null; } static Void n() { return "NotAllowed"; } static Object o() { return "Allowed"; }

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