Verwendet für den Java-Void Referenztyp?
Frage
Es gibt eine Java Void
- Groß V-- Referenztyp . Die einzige Situation, die ich je gesehen habe sie verwendet wird, ist Callable
s zu parametrieren
final Callable<Void> callable = new Callable<Void>() {
public Void call() {
foobar();
return null;
}
};
Gibt es noch andere Verwendungen für den Java Void
Referenztyp? Kann es überhaupt etwas anderes als null
zugewiesen werden? Wenn ja, haben Sie Beispiele haben?
Lösung
Void
hat Konvention für ein generisches Argument geworden, dass Sie nicht interessiert sind. Es gibt keinen Grund, warum Sie andere nichtinstanziierbare Typ verwendet werden soll, wie System
.
Es wird oft auch zum Beispiel Map
Werte in (obwohl Collections.newSetFromMap
verwendet Boolean
als Karten müssen nicht null
Werte annehmen) und java.security.PrivilegedAction
.
Ich schrieb einen Weblog-Eintrag auf Void
ein paar Jahre zurück.
Andere Tipps
Sie können Instanz Void mit Reflexionen erzeugen, aber sie sind für alles, was nicht sinnvoll. Void ist ein Weg, eine generische Methode gibt nichts anzuzeigen.
Constructor<Void> constructor = Void.class.getDeclaredConstructor();
constructor.setAccessible(true);
Void v = constructor.newInstance();
System.out.println("I have a " + v);
druckt etwas wie
I have a java.lang.Void@75636731
Future<Void>
funktioniert wie Charme . :)
Da gibt es keine öffentlichen Konstruktoren würde ich sagen, es kann nichts anderes als null
zugeordnet werden. Ich habe nur als Platzhalter für „Ich habe nicht diesen generischen Parameter verwenden muß“, wie Ihr Beispiel zeigt.
Es könnte auch in Reflexion verwendet wird, von dem, was seine Javadoc sagt:
The Void-Klasse ist eine uninstantiable Platzhalter Klasse einen Verweis auf das Klassenobjekt halten Sie das Java Schlüsselwort void darstellt.
All Wrapper-Klasse (Integer
, Byte
, Boolean
, Double
, etc.) enthält einen Verweis auf die entsprechenden primitive Klasse in einem statischen TYPE
Feld, zum Beispiel:
Integer.TYPE == int.class
Byte.TYPE == byte.class
Boolean.TYPE == boolean.class
Double.TYPE == double.class
Void
wurde ursprünglich als irgendwo erstellt einen Verweis auf den void
Typen zu setzen:
Void.TYPE == void.class
Aber Sie gewinnen nicht wirklich etwas von Void.TYPE
verwenden. Wenn Sie void.class
verwenden es ist viel klarer, dass Sie etwas mit dem void
Art tun.
Als Nebenwirkung, das letzte Mal, dass ich es versucht, Beanshell nicht erkannt void.class
, so dass Sie dort zu verwenden, Void.TYPE
.
Wenn Sie die Besuchermuster kann es sauberer sein anstelle von Object Void zu verwenden, wenn Sie sicher sein wollen, dass der Rückgabewert ist null,
Beispiel
public interface LeavesVisitor<OUT>
{
OUT visit(Leaf1 leaf);
OUT visit(Leaf2 leaf);
}
Wenn Sie Ihre Besucher umsetzen können Sie explizit OUT Void zu sein, so dass Sie Ihre Besucher wissen immer null zurück, statt Gegen mit
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;
}
}
Vor der Generika, es für das Reflection-API erstellt wurde, TYPE von Method.getReturnType () für eine void-Methode, die die anderen primitive Typklassen zurück zu halten.
EDIT: Von der JavaDoc von Void: "The Void-Klasse ist eine uninstantiable Platzhalter Klasse einen Verweis auf das Klassenobjekt, die das Java-Schlüsselwort ungültig zu halten". Vor Generics, ich bin mir dessen bewusst keine andere Nutzung als Reflexion.
Wie Sie nicht Void instanziiert, können Sie Apache commons Null-Objekt , so
Null aNullObject = ObjectUtils.Null;
Null noObjectHere = null;
in der ersten Zeile, Sie haben ein Objekt, so aNullObject != null
hält, während in der zweiten Zeile gibt es keinen Hinweis, so noObjectHere == null
hält
Das Plakats ursprüngliche Frage zu beantworten, denn dies ist die Nutzung ist zwischen dem „Nichts“ und „Nichts“, das sind ganz andere Dinge zu unterscheiden.
PS: Sag nein zu Null Objektmuster
Void ist erstellen, um seinen primitiven Hohlraumtyp wickelt. Jede primitive Art hat Referenzart es entspricht. Void wird verwendet, um eine generische Klasse oder die Verwendung einer generischen Methode zu instanziiert, ein generisches Argument Hexen Sie sind nicht daran interessiert. Und hier ist ein Beispiel ...
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());
}
});
}
hier, wie Sie sehen können, ich will nichts von dem Server, dass ich eine neue Registrierungen erstellen bin zu fragen, aber public interface AsyncCallback<T> { .... }
ist eine generische Schnittstelle, so dass ich Void liefern, da Generika akzeptieren keine primitiven Typen
Es wird auch allgemein auf Async-IO Fertigstellung Rückrufe verwendet, wenn Sie die Notwendigkeit, müssen nicht für ein Attachment
Objekt. In diesem Fall geben Sie an den IO-Betrieb null und implementieren CompletionHandler<Integer,Void>
.
Es kann seltener Fall sein, aber einmal, habe ich Void
in Aspekte Klassen.
Dies war ein Aspekt, der nach dem Verfahren läuft, die eine @Log
Anmerkung hat, und protokolliert die Methode zurückgegeben und einige Informationen, wenn der Methode Rückgabetyp nicht leer ist.
@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
}
}