Domanda

Esiste un Java Void - V maiuscola-- tipo di riferimento . L'unica situazione che io abbia mai visto usato è parametrizzare Callable s

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

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

È stato utile?

Soluzione

Void è diventato una convenzione per un argomento generico a cui non sei interessato. Non vi è alcun motivo per cui dovresti usare qualsiasi altro tipo non istantaneo, come System.

Viene spesso utilizzato ad esempio nei Map valori (sebbene Collections.newSetFromMap usi Boolean poiché le mappe non devono accettare null valori) e java.security.PrivilegedAction.

Ho scritto una voce nel blog il <=> qualche anno fa.

Altri suggerimenti

Puoi creare un'istanza di Void usando le riflessioni, ma non sono utili a nulla. Void è un modo per indicare che un metodo generico non restituisce nulla.

Constructor<Void> 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<Void> funziona come il fascino. :)

Dato che non ci sono nessun costruttore pubblico , Direi che non può essere assegnato altro che null. L'ho usato solo come segnaposto per & Quot; Non ho bisogno di usare questo parametro generico, & Quot; come mostra il tuo esempio.

Potrebbe anche essere usato in riflessione, da ciò che è Javadoc dice:

  

La classe Void è una classe segnaposto non attendibile per contenere un riferimento all'oggetto Class che rappresenta il vuoto della parola chiave Java.

Tutte le classi wrapper primitive (Integer, Byte, Boolean, Double, ecc.) contengono un riferimento alla classe primitiva corrispondente 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 da qualche parte per mettere un riferimento al void tipo:

Void.TYPE == void.class

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

A parte, l'ultima volta che l'ho provato, BeanShell non ha riconosciuto <=>, quindi devi usare <=> lì.

Quando usi il modello di visitatore può essere più pulito usare Void invece di Object quando vuoi essere sicuro che il valore restituito sarà null

Esempio

public interface LeavesVisitor<OUT>
{
   OUT visit(Leaf1 leaf);

   OUT visit(Leaf2 leaf);
}

Quando implementerai il tuo visitatore, puoi impostare esplicitamente OUT su Void in modo che tu sappia che il tuo visitatore restituirà sempre null, invece di usare Object

public class MyVoidVisitor implements LeavesVisitor<Void>
{
    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 di riflessione, per contenere TYPE restituito da Method.getReturnType () per un metodo void, corrispondente alle altre classi di tipi primitivi.

EDIT: da JavaDoc of Void: " La classe Void è una classe segnaposto non attendibile per contenere un riferimento all'oggetto Class che rappresenta la parola chiave Java void " ;. Prima di Generics, sono a conoscenza di nessun uso diverso dalla riflessione.

Poiché non è possibile creare un'istanza di Void, è possibile utilizzare Apache commons Null object , quindi

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

nella prima riga, hai un oggetto, quindi aNullObject != null trattiene, mentre nella seconda riga non ci sono riferimenti, quindi noObjectHere == null trattiene

Per rispondere alla domanda originale del poster, l'uso per questo è di distinguere tra " il nulla " e " niente " ;, che sono cose completamente diverse.

PS: dì no al modello di oggetto Null

Il vuoto è creato per avvolgere il suo tipo di vuoto primitivo. Ogni tipo primitivo ha il suo tipo di riferimento corrispondente. Void viene utilizzato per creare un'istanza di una classe generica o l'uso di un metodo generico, Argomenti generici che non ti interessano. Ecco un esempio ...

public void onNewRegistration() {
    newRegistrationService.createNewUser(view.getUsername(), view.getPassword(),
            view.getInitialAmount(), view.getCurrency(), new AsyncCallback<Void>() {
      @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<T> { .... } è un'interfaccia generica, quindi fornisco Void poiché i generici non accettano tipi primitivi

Viene anche comunemente utilizzato sui callback di completamento Async-IO quando non si ha la necessità di un oggetto Attachment. In tal caso si specifica null per l'operazione IO e si implementa CompletionHandler<Integer,Void>.

Può essere raro, ma una volta ho usato Void nelle classi di aspetto.

Questo era un aspetto che viene eseguito dopo i metodi con @Log annotazione e registra il metodo restituito e alcune informazioni se il tipo restituito dal metodo non è nullo.

 @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
         }
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top