2010-01-06 4 views
2

Disons que j'ai ceci:Y a-t-il une différence entre ces deux modes d'initialisation?

public class Whatever { 
    private ArrayList<String> myList = new ArrayList<String>(); 
    // more code goes here 
} 

ou disons que j'ai ceci:

public class Whatever { 
    private ArrayList<String> myList = null; 

    public Whatever() { 
    myList = new ArrayList<String>(); 
    } 
} 

Quelle est la différence entre ces deux initialisations de myList? Serait-il faux de préférer la première variante?

+1

Une note connexe, il est préférable de le faire: Liste privée myList = new ArrayList () – sateesh

+3

Il est encore plus préférable de le faire: 'Liste finale privée myList = new ArrayList ();' – Bombe

Répondre

13

La première variante instanciera toujours la liste de tableaux, la seconde uniquement lors de l'appel du constructeur par défaut. Signification pour la deuxième solution, vous devrez appeler le constructeur par défaut pour tout constructeur supplémentaire que vous ajoutez par exemple.

public class Whatever { 
    private final List<String> myList; 

    public Whatever() { 
    myList = new ArrayList<String>(); 
    } 

    public Whatever(String name) { 
    this(); 
    // Other stuff done 
    } 

    public Whatever(List<String> myList) { 
    this.myList = myList; 
    } 
} 

Le (deuxième) « paresseux » méthode d'initialisation peut-être mieux si vous ne l'utilisez pas toujours la liste (par exemple, si vous définissez la liste dans un autre constructeur directement comme dans mon exemple) et que vous voulez éviter de créer inutilement objets. (EDIT: J'ai changé le ArrayList à une interface et l'ai défini final .Il n'était pas une partie de la question mais c'est - comme mentionné dans les commentaires - la meilleure manière d'employer des collections de liste).

3

La machine virtuelle exécute d'abord le code tel que celui (en dehors du constructeur):

public class Whatever { 
    private ArrayList<String> myList = new ArrayList<String>(); 
    // more code goes here 
} 

Et seul code, puis comme celui-ci (à l'intérieur du constructeur):

public class Whatever { 
    private ArrayList<String> myList = null; 

    public Whatever() { 
    myList = new ArrayList<String>(); 
    } 
} 

Donc, à moins de l'ordre de l'exécution est en quelque sorte importante pour vous je suppose que la réponse de Daff est la bonne.

3

Dans cet exemple particulier, il n'y a aucune différence sauf que la première forme est plus courte.

Toutefois, si l'expression d'initialisation d'attribut génère (potentiellement) des exceptions, la seconde forme vous permet d'intercepter les exceptions ou de les déclarer comme étant lancées dans la signature du constructeur. Bien sûr, si vous avez plusieurs constructeurs, le second formulaire vous permet d'initialiser l'attribut différemment dans chaque constructeur ... ou d'utiliser le chaînage du constructeur pour initialiser l'attribut de la même façon ... ou de mélanger les deux styles d'initialisation .