2016-09-01 1 views
2

Je le code suivant:quelle est la différence dans le comportement de ce code?

public class Application extends ApplicationManager{ 

    public static void main(String[] args) { 
     ProcessUtility.enableProcessUtility(); 
     new Application().start(); 
    } 
} 

et le code classe ApplicationManager:

public class ApplicationManager { 

public ApplicationManager() { 

    String configPath = "file:home" + File.separator + "log4j.xml"; 
    System.setProperty("log4j.configuration", configPath); 
    logger = Logger.getLogger(ApplicationManager.class); 
} 

protected void start() { 
    logger.info("*** Starting ApplicationManager ***"); 
} 

quand je lance la classe d'application de la méthode de démarrage du parent est appelé, peut-il être appelé sans appeler le constructeur parent par défaut?

ma deuxième question est le code ci-dessus différent de ce code:

public class Application extends ApplicationManager{ 

    public static void main(String[] args) {  
     new Application().start(); 
    } 


    @Override 
    protected void start() { 
     ProcessUtility.enableProcessUtility(); 
     super.start(); 
    } 
} 

et la classe ApplicationManager comme ci-dessus.

c'est le code de la méthode statique:

public static void enableProcessUtility() { 
    isCommon = false; 
} 

merci à l'avance.

Répondre

4

L'appel d'une méthode non statique (votre méthode start) nécessite la création d'une instance de la classe qui contient la méthode (ou une sous-classe de cette classe). Créer une instance d'une classe nécessite d'appeler les constructeurs de la classe et toutes ses classes ancêtres. Par conséquent, vous ne pouvez pas éviter d'exécuter le constructeur parent par défaut. Comme pour la deuxième question, déplacer ProcessUtility.enableProcessUtility() à la méthode de début de la sous-classe signifie qu'elle sera exécutée chaque fois que vous appelez la méthode start. Cela dit, dans votre exemple, votre principal ne crée qu'une instance de Application et n'appelle qu'une seule fois pour cette instance. Par conséquent, ProcessUtility.enableProcessUtility() ne sera exécuté qu'une seule fois dans les deux extraits et le comportement sera identique.

EDIT: Une autre différence entre les deux extraits est que le premier extrait appelle ProcessUtility.enableProcessUtility() avant de créer l'instance Application, tandis que le second extrait crée d'abord l'instance puis appelle ProcessUtility.enableProcessUtility() à l'intérieur start de la sous-classe. Si le comportement des constructeurs (de la sous-classe ou de la super classe) est affecté par l'appel à ProcessUtility.enableProcessUtility(), les deux extraits peuvent produire des sorties différentes.

+0

Quand j'exécute les deux codes, j'obtiens des résultats différents comment cela peut-il arriver ?, Je sais qu'il doit appeler le constructeur parent mais un code du constructeur parent ne s'exécute pas dans l'une de ces implémentations! – flashDisk

+0

@flashDisk Dans le deuxième extrait, les constructeurs sont exécutés avant 'ProcessUtility.enableProcessUtility()'. Peut-être que c'est la cause du comportement différent. – Eran

+0

le comportement correct est la deuxième mise en œuvre, mais je ne trouve toujours pas pourquoi! – flashDisk

1

Votre première question est répondue ici https://stackoverflow.com/a/10508202/2527075

Quant à votre deuxième question, le constructeur super sera appelée avant l'appel ProcessUtility dans le second exemple, où, dans le premier exemple l'appel ProcessUtility vient en premier.

+0

lorsque le constructeur du parent est appelé?, Lors de l'appel de l'une de ses méthodes? ou lors de l'appel du constructeur de la sous-classe? – flashDisk

+0

Chaque constructeur fait d'abord un super implicite(); appel. Ainsi, chaque constructeur de sous-classe appelle d'abord le super constructeur. –