Utilisations du type de référence Java Void?

Il existe un type de référence Java Void – majuscule V–. La seule situation que je connaisse est de paramétrer Callable s

 final Callable callable = new Callable() { public Void call() { foobar(); return null; } }; 

Existe-t-il d’autres utilisations du type de référence Java Void ? Peut-on jamais lui atsortingbuer autre chose que null ? Si oui, avez-vous des exemples?

Void est devenu une convention pour un argument générique qui ne vous intéresse pas. Il n’y a aucune raison pour que vous utilisiez un autre type non instanciable, tel que System .

Il est également souvent utilisé par exemple dans les valeurs de Map (bien que Collections.newSetFromMap utilise Boolean valeurs Boolean car les cartes n’ont pas à accepter null valeurs null ) et java.security.PrivilegedAction .

Il y a quelques années, j’ai écrit un blog sur Void .

Vous pouvez créer une instance de Void en utilisant des reflections, mais elles ne sont utiles pour rien. Void est un moyen d’indiquer qu’une méthode générique ne retourne rien.

 Constructor constructor = Void.class.getDeclaredConstructor(); constructor.setAccessible(true); Void v = constructor.newInstance(); System.out.println("I have a " + v); 

imprime quelque chose comme

 I have a java.lang.Void@75636731 

Future fonctionne comme un charme. 🙂

Étant donné qu’il n’ya pas de constructeurs publics , je dirais qu’on ne peut pas leur atsortingbuer autre chose que null . Je l’ai seulement utilisé comme un espace réservé pour “je n’ai pas besoin d’utiliser ce paramètre générique”, comme le montre votre exemple.

Il pourrait également être utilisé en reflection, à partir de ce que dit Javadoc :

La classe Void est une classe d’espace réservé instable pour contenir une référence à l’object Class représentant le mot-clé Java vide.

Toutes les classes d’encapsulation primitives ( Integer , Byte , Boolean , Double , etc.) contiennent une référence à la classe primitive correspondante dans un champ TYPE statique, par exemple:

 Integer.TYPE == int.class Byte.TYPE == byte.class Boolean.TYPE == boolean.class Double.TYPE == double.class 

Void été initialement créé comme lieu de référence au type de void :

 Void.TYPE == void.class 

Cependant, vous ne gagnez rien en utilisant Void.TYPE . Lorsque vous utilisez void.class il est beaucoup plus clair que vous faites quelque chose avec le type void .

En passant, la dernière fois que je l’ai essayé, BeanShell n’a pas reconnu void.class , vous devez donc utiliser Void.TYPE .

Lorsque vous utilisez le modèle de visiteur, il peut être plus propre d’utiliser Void au lieu d’Object lorsque vous voulez être sûr que la valeur de retour sera nulle.

Exemple

 public interface LeavesVisitor { OUT visit(Leaf1 leaf); OUT visit(Leaf2 leaf); } 

Lorsque vous allez implémenter votre visiteur, vous pouvez explicitement définir OUT comme Void pour que vous sachiez que votre visiteur renverra toujours null, au lieu d’utiliser Object

 public class MyVoidVisitor implements LeavesVisitor { Void visit(Leaf1 leaf){ //...do what you want on your leaf return null; } Void visit(Leaf2 leaf){ //...do what you want on your leaf return null; } } 

Avant les génériques, il était créé pour l’API de reflection, pour contenir TYPE renvoyé par Method.getReturnType () pour une méthode void, correspondant aux autres classes de type primitives.

EDIT: à partir de JavaDoc of Void: “La classe Void est une classe d’espace réservé inaltérable pour contenir une référence à l’object Class représentant le mot clé Java vide”. Avant Generics, je ne suis conscient de rien d’autre que la reflection.

Void est create pour envelopper son type vide primitif. Chaque type primitif a son type de référence correspondant. Void est utilisé pour instancier une classe générique ou utiliser une méthode générique, Un argument générique qui ne vous intéresse pas et voici un exemple …

 public void onNewRegistration() { newRegistrationService.createNewUser(view.getUsername(), view.getPassword(), view.getInitialAmount(), view.getCurrency(), new AsyncCallback() { @Override public void onFailure(Throwable caught) { } @Override public void onSuccess(Void result) { eventBus.fireEvent(new NewRegistrationSuccessEvent()); } }); } 

ici, comme vous pouvez le voir, je ne veux rien du serveur que je demande pour créer de nouvelles inscriptions, mais public interface AsyncCallback { .... } est une interface générique donc je fournit Void puisque les génériques don n’accepte pas les types primitifs

Comme vous ne pouvez pas instancier Void, vous pouvez utiliser l’ object Apache commons Null , donc

 Null aNullObject = ObjectUtils.Null; Null noObjectHere = null; 

dans la première ligne, vous avez un object, donc aNullObject != null est aNullObject != null , alors que dans la deuxième ligne il n’y a pas de référence, donc noObjectHere == null détient

Pour répondre à la question originale de l’affiche, l’usage consiste à différencier «le rien» et «rien», qui sont des choses complètement différentes.

PS: Dites non au motif d’object nul

Il est également couramment utilisé sur les rappels d’achèvement Async-IO lorsque vous n’avez pas besoin d’un object Attachment . Dans ce cas, vous indiquez null à l’opération IO et implémentez CompletionHandler .

Cela peut être rare, mais une fois, j’ai utilisé Void dans les classes d’aspect.

Cet aspect s’exécute après les méthodes qui ont une annotation @Log et consigne la méthode renvoyée et quelques informations si le type de retour de la méthode n’est pas vide.

  @AfterReturning(value = "@annotation(log)", returning = "returnValue", argNames = "joinPoint, log, returnValue" ) public void afterReturning(final JoinPoint joinPoint, final Log log, final Object returnValue) { Class returnType = ((MethodSignature) joinPoint.getSignature()) .getReturnType(); if (Void.class.isAssignableFrom (returnType)) ) { //Do some log } }