2016-07-03 1 views
1

TLDR: Existe-t-il un moyen de forcer une sous-classe à avoir un constructeur vide quand le super ne le fait pas?Sérialisable en prolongeant avec le constructeur vide?

Je dois être pour initialiser une classe non sérialisable, TravelTimeDataArray, à partir d'un conteneur de données sérialisé. Le TravelTimeDataArray ne peut pas être sérialisé car il n'implémente pas l'interface Serializable, ne dispose pas d'un constructeur vide et utilise un champ non sérialisable de type Link. Ma première pensée a été de l'étendre en tant que classe sérialisable. Au lieu d'utiliser un Link, je peux utiliser une chaîne sérialisable de son attribut ID et ajouter le constructeur vide. Puisque le super n'a pas de constructeur vide, j'obtiens une erreur avec le constructeur vide de la sous-classe. Existe-t-il un moyen de forcer une sous-classe à avoir un constructeur vide quand le super ne le fait pas?

+0

Vous n'avez pas besoin d'un constructeur vide dans la classe Serializable. – EJP

+0

Je sais. J'espérais que nous pourrions en quelque sorte surcharger le constructeur par défaut du super pour utiliser le constructeur vide de la sous-classe et rendre ainsi la sous-classe sérialisable. – andrew

+1

Cela n'a pas de sens. Un constructeur généré par défaut * utilisera * le constructeur par défaut de la classe de base; personne n'appellera le constructeur par défaut d'une classe sérialisable pendant la désérialisation; et la classe de base n'a * pas * un constructeur par défaut, * qui est le problème réel. * Vous devez prendre du recul et réfléchir. – EJP

Répondre

2

Selon The Serializable Interface:

Une classe Serializable doit effectuer les opérations suivantes:

  • implémentent l'interface java.io.Serializable
  • Identifier les champs qui doivent être sérialisable (Utilisez les serialPersistentFields membre pour les déclarer explicitement sérialisables ou utiliser le mot-clé transitoire pour désigner les champs non sérialisables.)
  • Avoir accès au constructeur sans arg de ses premiers superclasse non sérialisable

Un constructeur sans arg de première superclasse d'un objet non sérialisable est nécessaire d'avoir accès, car il sera appelé en désérialisation l'objet. Sinon, une exception sera levée. Notez que la sérialisation d'un objet n'appelle pas le constructeur par défaut de sa superclasse et qu'aucune exception ne sera levée.

Si l'extension d'une classe n'est pas un must, vous pouvez envisager d'utiliser l'encapsulation comme suit:

public class Foo implements Serializable { 

    private final double[] timeSum; 
    private final int[] timeCnt; 
    private final double[] travelTimes; 
    private final String linkId; 
    private final transient TravelTimeDataArray ttDA; 


    public Foo(TravelTimeDataArray ttDA) { 
     this.ttDA = ttDA; 
     this.timeSum = ttDA.getTimeSum(); 
     this.timeCnt = ttDA.getTimeCnt(); 
     this.travelTimes = ttDA.getTravelTimes(); 
     this.linkId = ttDA.getLink().getId(); 
    } 

    // Methods 
} 

Si vous n'avez pas besoin d'accéder TravelTimeDataArray dans votre classe, vous pouvez sauter le champ transient TravelTimeDataArray ttDA. J'espère que cela peut aider.

+0

Oui, c'est l'approche que j'ai prise. J'espérais qu'il y avait un peu de magie noire Java pour contourner le «constructeur sans-arg de sa première superclasse non-sérialisable». Après tout, nous pouvons utiliser Reflection pour exposer des classes privées. – andrew