2012-01-17 22 views
13

Quando preferire uno rispetto all'altro? Qual è lo scopo del metodo mostrato di seguito?Qual è la differenza tra "new A()" e "A.newInstance()"?

class A { 
    public static A newInstance() { 
     A a = new A(); 
     return a ; 
    } 
} 

Qualcuno può spiegarmi le differenze tra queste due chiamate?

+1

Comunemente, A.newInstance viene utilizzato per il modello di disegno singleton. –

risposta

16

newInstance() è spesso usato come un modo per creare un'istanza di un oggetto senza chiamare direttamente costruttore di default dell'oggetto. Ad esempio, è spesso utilizzato per implementare un design pattern Singleton:

public class Singleton { 
    private static final Singleton instance = null; 

    // make the class private to prevent direct instantiation. 
    // this forces clients to call newInstance(), which will 
    // ensure the class' Singleton property. 
    private Singleton() { } 

    public static Singleton newInstance() { 
     // if instance is null, then instantiate the object by calling 
     // the default constructor (this is ok since we are calling it from 
     // within the class) 
     if (instance == null) { 
      instance = new Singleton(); 
     } 
     return instance; 
    } 
} 

In questo caso, il programmatore costringe il cliente a chiamare newInstance() per recuperare un'istanza della classe. Questo è importante perché la semplice fornitura di un costruttore predefinito consente al client di accedere a più istanze della classe (che va contro la proprietà Singleton).

Nel caso di Fragment s, fornire un metodo di produzione statico newInstance() è una buona pratica poiché spesso si desidera aggiungere argomenti di inizializzazione all'oggetto appena istanziato. Piuttosto che avere il client chiama il costruttore predefinito e imposta manualmente gli argomenti del frammento, possiamo fornire un metodo newInstance() che faccia questo per loro. Ad esempio,

public static MyFragment newInstance(int index) { 
    MyFragment f = new MyFragment(); 
    Bundle args = new Bundle(); 
    args.putInt("index", index); 
    f.setArguments(args); 
    return f; 
} 

Nel complesso, mentre la differenza tra i due è per lo più solo una questione di progettazione, questa differenza è molto importante perché fornisce un ulteriore livello di astrazione e rende il codice molto più facile da capire.

+0

ottimo, mi fa pensare più facilmente, molte grazie – rex

+0

Hm, ma non potresti avvolgere lo stesso codice in un costruttore? 'classe pubblica MyFragment { MyFragment (argomenti del pacchetto) {this.setArguments (args) ...} MyFragment (int index) {Bundle args = new Bundle(); args.putInt (...); questo (args)} – Karsten

+0

stai provando a cambiare il riferimento della variabile finale "istanza", il suo errore, non è vero? –

1

Nei tuoi esempi sono equivalenti e non esiste un vero motivo per scegliere l'uno sull'altro. Tuttavia, l'uso di newInstance è comunemente usato se eseguire alcune inizializzazioni prima di restituire un'istanza della classe. Se ogni volta che richiedi una nuova istanza della classe chiamando il suo costruttore, finisci per impostare un gruppo di variabili di istanza prima di poter usare l'oggetto, allora avrebbe più senso che il metodo newInstance eseguisse quell'inizializzazione e ti restituisse un oggetto che è pronto per l'uso.

Ad esempio, Activity s e Fragment s non sono inizializzati nei relativi costruttori. Al contrario, sono generalmente inizializzati durante onCreate. Pertanto, è prassi comune che il metodo newInstance accetti i parametri che l'oggetto dovrà utilizzare durante l'inizializzazione e li memorizza in un pacchetto che l'oggetto può leggere in seguito. Un esempio di questo può essere visto qui:

Sample class with newInstance method

0

new() è una parola chiave utilizzata per creare un oggetto e può essere usato mentre sappiamo il nome della classe
new instance() è un metodo utilizzato per creare un oggetto e può essere utilizzato quando non conosciamo il nome della classe

Problemi correlati