Il est possible de sérialiser le «vide» primitif par défaut, pourquoi l'objet «vide» s'étend sur Serializable?
La rotinimployation Demandez à une erreur de compilation disant «void ne se situant pas dans sa liaison» car elle ne s'étend pas sérialisable.
Bien que «Somemethod» soit déclaré avec «Void», ce ne serait pas un problème. P> public interface Root<R extends Serializable> extends Serializable {
R someMethod();
}
public class RootImplementation implements Root<Void> {
public Void someMethod() {
return null;
}
}
9 Réponses :
Le Javadoc est clair: p>
La classe de vide est une non négligeable classe d'espace réservé pour tenir une référence à l'objet de la classe représentant le Mot-clé Java P> blockQuote>
Parce que vous ne pouvez pas l'utiliser, il n'a pas besoin d'être sérialisable (sauf les trucs de réflexion). P>
Et pour la deuxième question: void! = vide (si vous pensez à! = dans une expression non Java) p>
oui
void code> est un mot clé et
void code> une classe. p>
Pour citer les Javadocs: P>
La classe Void est une classe d'espace réservée insensante pour contenir une référence à l'objet de la classe représentant le mot clé Java vide. p> blockQuote>
Étant donné que la classe est insensantasible, elle ne peut pas être désérialisée. ERGO Aucun besoin de soutien de sérialisation. P>
Il est possible de sérialiser le primitif 'vide' par défaut, pourquoi pas l'objet 'vide' s'étendre Sérialisable? P> blockQuote>
vide ne porte pas de valeur, donc cela n'a aucun sens de le sérialiser. P>
Cela ne signifie-t-il pas que VOID! = vide? P> blockQuote>
vrai, juste comme int! = Entier. Mais lorsque vous serialisez et désérialisez deux INTS, newint == oldint (je veux dire
int code>, pas
integer code> !!!). Aucune construction de ce type ne serait possible avec
void code>. Cela n'a rien de sens pour ne rien sérialiser. P>
Ce serait utile que si vous aviez un champ de type void, ce qui n'a aucun sens. Vous auriez également besoin d'attribuer une instance, ce qui n'a pas de sens. Tant que vous ne le faites pas, vous pouvez sérialiser l'instance de la classe contenant le champ vide. Afin de créer une instance de vide, vous devez utiliser la réflexion afin d'utiliser le constructeur privé.
public class VoidSerializerDemo implements Serializable { private Void v; public static void main(String[] args) throws Exception { final VoidSerializerDemo instance = new VoidSerializerDemo(); final ByteArrayOutputStream baos = new ByteArrayOutputStream(); final ObjectOutputStream oos = new ObjectOutputStream(baos); oos.writeObject(instance); System.out.println("OK: null works"); final Constructor<Void> constructor = Void.class.getDeclaredConstructor(); constructor.setAccessible(true); instance.v = constructor.newInstance(); oos.reset(); System.out.println("Going to throw"); oos.writeObject(instance); } }
D'autres ont expliqué pourquoi il n'a pas de sens pour un type qui ne peut jamais être instancié à mettre en œuvre Pour résoudre le code de votre édition, je pense que vous devriez simplement modifier le sérialisable code> et pourquoi
vide code> n'est pas une primitive ou sérialisable. < / p>
r étend sérialisable code> lié à juste
r code>. La plupart des types génériques code> sérialisable code> n'exigent pas que leurs paramètres de type soient
sérialisables code> ... Ils indiquent simplement que si vous leur mettez quelque chose qui n'est pas sérialisable, ils ont gagné 't être sérialisable non plus. Il s'agit généralement d'une bonne pratique, car il est essentiel d'essayer trop fort pour appliquer la sérialisalisabilité au niveau du compilateur peut vous mordre (comme vous le voyez ici). P>
OK, en réponse à votre exemple, non si vous avez changé la méthode sur Ce que vous voulez faire est de déclarer un paramètre de type en tant que "retournera NULL". Le vide est généralement un bon choix pour cela, mais pour le voivenir au travail, le type de retour doit être objet. Le vide ne peut pas implémenter chaque interface dans l'API simplement parce que quelqu'un pourrait vouloir l'utiliser pour indiquer un retour nul sur un paramètre de type. P>
Il y a trois façons de regarder votre problème: p>
VOID code>, il ne fonctionnerait pas, car la méthode doit avoir un type de retour (même si Java permet désormais des types de retour covariant dans méthodes remplacées). La discussion sur
void code> confond le problème. P>
Merci d'avoir répondu. 1. À mesure que Colind mentionne; La plupart desserront la Serialziable du type générique car la déclaration de classe elle-même implique de ne pas enregistrer des objets non sérialisables sur la mise en œuvre. Bien que aussi peu de gens vont utiliser l'interface et faire des implémentations, je souhaite que cela soit aussi utile que possible de ne pas faire une erreur. 2. Je ne veux pas que l'extension éventuelle soit capable de retourner autre chose que le vide (ou NULL dans ce cas depuis le vide doit être utilisé). 3. Voici comment j'ai fait pour le moment, même si je voulais poser la question et voir si quelqu'un avait une meilleure solution.
@Tomas Forsman, une classe implémentée Serializable ne signifie pas que cela peut être sérialisé. Considérez ceci: Vid vide privé WriteObject (ObjectOutputSteam Out) {Jetez NOUVELLE NOTSERIALIZABLEEXCEPTION (GetClass (). GetName ());} Code> J'utilise cela pour vous assurer que certaines classes étendues n'atteignent jamais le formulaire de sérialisation.
Étant donné que votre méthode ne renvoie rien, mais null, vous pouvez remplacer le vide avec quelque chose comme ce qui suit: p> s'appelle d'une primitive, le vide montre l'absence d'une valeur , une méthode renvoyant le vide ne renvoie pas une valeur de type vide à la place, il ne renvoie pas littéralement rien. p> p> VOID code> est uniquement destiné à montrer qu'une méthode ne peut que renvoyer
null code>, malheureusement, il n'y a aucun moyen de déclarer le type null directement. Pour le void JVM, seul un objet d'extension normal de classe normale et, en tant que tel, ne peut pas être utilisé en place pour d'autres classes ou interfaces, cela facilite votre exemple.
Je vais le mettre ici en tant que Comminity-wiki
Tu peux (DE) Serialize résultat du code p> java.lang.void code> B / C Vous pouvez l'initialiser avec NULL uniquement. Java ne se soucie pas si une classe implémente
java.io.rsérialisable code> si c'est
null code>. P>
public class VoidOut implements java.io.Serializable{
int x=1;
Void v = null;
public static void main(String[] args) throws Throwable{
VoidOut v = new VoidOut();
System.out.println(v);
ByteArrayOutputStream b =new ByteArrayOutputStream(256);
ObjectOutputStream o = new ObjectOutputStream(b);
o.writeObject(v);
o.close();
ObjectInputStream in =new ObjectInputStream(new ByteArrayInputStream(b.toByteArray()));
System.out.println(in.readObject());
}
}
Si vous utilisez une bibliothèque Apache Commons, il y a un org.apache.commons.lang3.Objectutils.Null qui s'étend sérialisable. p>
Il n'y a pas de vide primitif. Et NOID n'a jamais eu d'instance, et je ne peux pas penser à un cas d'utilisation où ce serait un champ sur une classe. Mais si c'est le cas, vous pouvez toujours le rendre transitoire, car il sera toujours null de toute façon.
Qu'entendez-vous par «il est possible de sérialiser le« voilé »primitif par défaut»? Il n'y a pas de données à sérialiser ... Pouvez-vous donner un exemple de ce que vous voulez dire?
Jon Skeet peut sérialiser
void code>!
Vous peut B> Serialize Void, principalement B / C, vous ne pouvez pas avoir d'instance de la classe (constructor.setabixible (true) et dangereux.AllocateInstance (void.class) ne compte pas)
Note latérale: Sérialisable est censé être une interface implicite / marquage.