Initialiser le champ avant le super constructeur d'exécution?

En Java, est-il possible d'initialiser un champ avant le super constructeur fonctionne?

Même le plus laid des hacks je peux venir avec sont rejetés par le compilateur:

class Base
{
    Base(String someParameter)
    {
        System.out.println(this);
    }
}

class Derived extends Base
{
    private final int a;

    Derived(String someParameter)
    {
        super(hack(someParameter, a = getValueFromDataBase()));
    }

    private static String hack(String returnValue, int ignored)
    {
        return returnValue;
    }

    public String toString()
    {
        return "a has value " + a;
    }
}

Remarque: Le problème a disparu quand je suis passé de l'héritage de la délégation, mais je voudrais quand même savoir.

  • êtes-vous essayer de pré-initialiser le champ a?
  • Je ne pense pas que vous pouvez le faire. Tout d'initialisation que vous faites dans une classe (même si c'est en dehors du constructeur) est déplacé à chaque constructeur après la super appel. Ainsi, le super constructeur est toujours exécuté avant que le champ de l'initialisation.
  • depuis a n'est accessible que dans Derived, pourquoi est-il important qu'il obtient initialisé avant super() est appelé? Initialisation après ne pas faire une différence dans l'exemple de votre fournir (sauf si vous appelez une méthode surchargée à partir du constructeur de Base, qui commence à avoir une odeur assez louche).
  • Efficace Java Article 17: "les Constructeurs ne doivent pas invoquer des méthodes substituables, directement ou indirectement, ( ... ) Si la méthode de remplacement dépend de l'initialisation effectuée par le constructeur de sous-classe, la méthode ne fonctionnera pas comme prévu."
  • peut une dernière variable sera initialisée dans le constructeur?
  • Ouais, bien sûr. Recherchez Immuable classes.
  • Din sais pas qui! Merci.
  • Laide Hack: Créer la classe Dérivée directement dans le bytecode java comme dans cette réponse: stackoverflow.com/questions/3278865/...
  • En fait, cela fait une différence dans mon exemple, car System.out.println(this) appelle en interne toString(), qui est surchargé d'imprimer la valeur de a.
  • Oui, c'était mon point de vue - c'est la seule situation où il fait la différence et qui vous voudrez probablement à éviter.
  • Je pense que ce qu'on a une meilleure solution qui peut être aussi bien utilisé pour ceci: stackoverflow.com/questions/2303604/..., Peut-être au lieu d'un hack() fonction que vous aurez besoin de faire un Hack de la classe, et vous pouvez vraiment utiliser la solution dans le lien

InformationsquelleAutor fredoverflow | 2013-03-28