Utilizza per il tipo di riferimento vuoto di Java?

Esiste un tipo di riferimento Void Java – maiuscolo V–. L’unica situazione che abbia mai visto è quella di parametrizzare Callable s

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

Ci sono altri usi per il tipo di riferimento di Java Void ? Può mai essere assegnato qualcosa di diverso da null ? Se sì, hai degli esempi?

    Void è diventato una convenzione per un argomento generico a cui non sei interessato. Non c’è motivo per cui tu debba utilizzare qualsiasi altro tipo non istantaneo, come System .

    Viene anche spesso utilizzato, ad esempio, nei valori Map (sebbene Collections.newSetFromMap utilizzi Boolean quanto le mappe non devono accettare valori null ) e java.security.PrivilegedAction .

    Ho scritto una voce del blog su Void alcuni anni fa.

    Puoi creare un’istanza di Void usando i riflessi, ma non sono utili per nulla. Void è un modo per indicare che un metodo generico non restituisce nulla.

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

    stampa qualcosa di simile

     I have a java.lang.Void@75636731 

    Future funziona come fascino. 🙂

    Dato che non ci sono costruttori pubblici , direi che non può essere assegnato nulla diverso da null . L’ho usato solo come segnaposto per “Non ho bisogno di usare questo parametro generico”, come mostra il tuo esempio.

    Potrebbe anche essere usato in riflessione, da quello che dice Javadoc :

    La class Void è una class di segnaposto non affidabile per contenere un riferimento all’object Class che rappresenta la parola chiave Java void.

    Tutte le classi wrapper primitive ( Integer , Byte , Boolean , Double , ecc.) Contengono un riferimento alla corrispondente class primitiva in un campo TYPE statico, ad esempio:

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

    Void stato inizialmente creato come un luogo in cui inserire un riferimento al tipo di void :

     Void.TYPE == void.class 

    Tuttavia, non si guadagna nulla usando Void.TYPE . Quando usi void.class è molto più chiaro che stai facendo qualcosa con il tipo void .

    Per void.class , l’ultima volta che l’ho provato, BeanShell non ha riconosciuto void.class , quindi devi usare Void.TYPE lì.

    Quando usi il pattern visitor , può essere più pulito usare Void invece di Object quando vuoi essere sicuro che il valore restituito sarà nullo

    Esempio

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

    Quando implementi il ​​tuo visitatore, puoi esplicitamente impostare OUT come Void in modo che tu sappia che il tuo visitatore restituirà sempre null, invece di usare 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; } } 

    Prima dei generici, è stato creato per l’API reflection, per contenere TYPE restituito da Method.getReturnType () per un metodo void, corrispondente alle altre classi di tipi primitivi.

    EDIT: Da JavaDoc of Void: “La class Void è una class di segnaposto non affidabile per contenere un riferimento all’object Class che rappresenta la parola chiave Java void”. Prima di Generics, sono a conoscenza di alcun uso diverso dalla riflessione.

    Il vuoto è creato per avvolgere il suo tipo di vuoto primitivo. Ogni tipo primitivo ha il suo tipo di riferimento corrispondente. Il vuoto è usato per istanziare una class generica o l’uso di un metodo generico, un argomento generico di cui non sei interessato ed ecco un esempio …

     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()); } }); } 

    qui, come puoi vedere, non voglio nulla dal server che sto chiedendo di creare una nuova registrazione, ma public interface AsyncCallback { .... } è un’interfaccia generica, quindi fornisco Void dal momento che i generici donano non accettare tipi primitivi

    Poiché non è ansible creare un’istanza di Void, è ansible utilizzare l’ object Null di Apache , quindi

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

    nella prima riga, hai un object, quindi aNullObject != null detiene, mentre nella seconda riga non c’è riferimento, quindi noObjectHere == null detiene

    Per rispondere alla domanda originale del poster, l’uso di questo è di distinguere tra “il nulla” e “niente”, che sono cose completamente diverse.

    PS: dire no al pattern di oggetti Null

    Viene anche comunemente usato su callback di completamento Async-IO quando non si ha la necessità di un object Attachment . In tal caso, si specifica null all’operazione IO e si implementa CompletionHandler .

    Potrebbe essere un caso raro, ma una volta ho usato Void nelle classi di aspetto.

    Questo era un aspetto che viene eseguito dopo i metodi che hanno un’annotazione @Log e registra il metodo restituito e alcune informazioni se il metodo restituito non è vuoto.

      @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 } }