2010-09-30 1 views
6

Domanda semplice. Un amico della mente ha scritto il codice simile a questo (che è solo per spiegare la mia domanda, non è utile a tutti ....)Convenzione in java - "nuovo" al di fuori del costruttore/metodo?

class Example{ 
    private int[] tab = new int[10]; 
    public Example() { 
     for(int i = 0 ; i < 10 ; i++) 
      tab[i] = (int)(Math.random()*100); 
     for(int i = 0 ; i < 10 ; i++) 
      System.out.println(tab[i]); 
    } 
    public static void main(String[] arg) { 
     Example ex = new Example(); 
    } 
} 

Gli ho detto che dovrebbe mettere la new all'interno del costruttore

Quando mi chiede perché, non so cosa rispondere: non ho avuto un argomento preciso se non "è meglio così". Per come lo imparo, puoi inizializzare le variabili con tipi di base (int, double ...) ma per gli array dovresti farlo nel costruttore.

Quindi:

  • è davvero meglio?
  • Ci sono dei buoni motivi: convenzione, stile?
  • Cambia qualcosa come meno/più memoria utilizzata?

Non sto considerando il caso in cui il numero di elementi può variare. Sarà SEMPRE 10

risposta

7
  • è davvero meglio?

Non proprio, IMO.

  • c'è qualche buona ragione: convenzione? stile ?

Ci possono essere motivi validi per scegliere un modo sopra l'altro è quando si dispone di più costruttori, o quando i valori iniziali dipendono argomenti del costruttore; per esempio.

private int[] tab; 

public Example(int size) { 
    tab = new int[size]; 
    for (int i = 0; i < size; i++) 
     tab[i] = (int) (Math.random() * 100); 
} 

o

private int[] tab = new int[10]; 

public Example(int initial) { 
    for (int i = 0; i < 10; i++) 
     tab[i] = initial; 
} 

public Example() { 
    for (int i = 0; i < 10; i++) 
     tab[i] = (int) (Math.random() * 100); 
} 

A parte questo (e nel tuo esempio) non ci sono regole generali su questo. È una questione di gusti personali.

  • cambia qualcosa come meno/più memoria utilizzata?

Nel tuo esempio non farà differenza. In generale, potrebbe esserci una piccola differenza nelle dimensioni del codice o nelle prestazioni, ma non vale la pena preoccuparsi.

In breve, non penso che il tuo suggerimento per il tuo amico abbia una base razionale.

Il modo in cui l'ho imparato, è possibile inizializzare le variabili con tipi di base (int, double ...) ma per gli array dovresti farlo nel costruttore.

Dovresti disimparare che ... o almeno riconoscere che è solo una preferenza personale.

+0

Con più costruttori è ancora possibile utilizzare la parola chiave this() in un altro costruttore per chiamare uno esistente. – Koekiebox

+0

@Koekiebox - sì, se aiuta. Nel mio esempio non sarebbe d'aiuto. –

+0

capito! La mia conoscenza di java è molto bacica ed è stata qualcosa che mi è stata insegnata qualche tempo fa durante un breve progetto. L'ho accettato come un dato di fatto ma la domanda è stata sollevata oggi, mentre sputavo con il mio amico. –

4

In realtà preferisco usare il metodo esterno. Se ha aggiunto un costruttore e aveva

private int[] foo = new int[10]; 

public Example() { } 

public Example(int somethVar) { } 

Quindi entrambi i costruttori avrebbero un array foo pronto per l'uso. Vedi this article poiché il compilatore Java è abbastanza intelligente da copiare solo quella roba nel costruttore, quindi non è affatto meglio.

3

Non sono a conoscenza di vantaggi funzionali/prestazionali di un metodo o dell'altro. Ma ecco alcuni pensieri perché l'inizializzazione della variabile immediatamente può essere migliore.

  1. Se si dispone di tre diversi costruttori, non si desidera inserire new int[10]; in ciascuno, giusto?
  2. Leggibilità. Quando vedo la variabile usata nel codice, posso fare "ctrl-clic" nel mio IDE e vedere sia il tipo che il valore di esso. Non devo cercare un posto dove è stato inizializzato.
+1

Commento a 1. Dipende, se un costruttore fa 'new int [2]', e l'altro 'new int [10]' (hey, di solito è la ragione per avere più costruttori), allora li vuoi inizializzato in costruttori. –

+0

@Alexander Il commento è applicabile a entrambi 1 e 2 :) Sì, più costruttori offrono maggiore libertà. –

+0

In quel caso, il loro era solo un costruttore. Infatti, se la dimensione può variare, è necessario inizializzarla in ogni costruttore. –

1

mi piace per inizializzare le mie variabili di istanza non statici nel costruttore,

fare questo rende più facile per gli altri a riconoscere che la strategia viene seguita quando il costruttore si correva.

Ogni nuovo oggetto avrà la propria istanza tab, quindi nel tuo esempio non importa se la classe rimane la stessa.

L'unica volta che uso un costruttore è quando ho bisogno di passare i parametri che si applica a tutto l'oggetto e non ad un metodo specifico, ad esempio:

public class Authenticate{ 
    private String usrname; 
    private String password; 
    public Authenticate(String usernameParam,String passwordParam){ 
     this.usrname = usernameParam; 
     this.password = passwordParam; 
    } 

    public void login(){ 
     //TODO put some code here to authenticate against some server using some technology. 
    } 

    public String getDepartment(){ 
     //Get the department where the username and password variable would be necessary if 
     //login hasn't been called. 
    } 
} 
+1

Non è necessario inizializzare esplicitamente quei membri vars a 'null' poiché 1) saranno inizializzati a' null' di default anwyay, e 2) si assegnano esplicitamente valori nel costruttore. – Grodriguez

+0

Sì, le stai inizializzando due volte. –

+0

Quale sarebbe il valore predefinito per usrname e password se non li assegno? Per quanto mi riguarda, la JMV la assegnerà automaticamente a null. Mi piace solo vedere il codice. – Koekiebox

3

Questo è destinata probabilmente ad essere una domanda stupida e quindi essere votati, ma ... perché il tuo amico non usa un blocco di inizializzazione per, sai, l'inizializzazione?

Capisco perfettamente il motivo per cui non vuole metterlo nel costruttore perché potrebbe non essere il costruttore e ripetendo all'infinito il codice di inizializzazione in ogni costruttore è ovviamente male durante l'utilizzo di un costruttore no-arg e basandosi su le chiamate automatiche a this() possono essere snervanti.

Quindi ...

Ecco il codice che userei io:

class Example{ 
    private int[] tab; 

    { tab = new int[10]; } 

    public Example() { 
     for(int i = 0 ; i < 10 ; i++) 
      tab[i] = (int)(Math.random()*100); 
     for(int i = 0 ; i < 10 ; i++) 
      System.out.println(tab[i]); 
    } 
    public static void main(String[] arg) { 
     Example ex = new Example(); 
    } 
} 

mi piacerebbe anche approssimativamente usare quella struttura: dichiarare i miei soci privati, mettere nel blocco di inizializzazione, dichiarare la mia costruttori, dichiara il resto dei miei metodi.

+1

IMHO, è giusto così) –

+0

Penso che non l'abbia usato perché non l'ha ancora imparato ... essere in Java101 per circa 3 settimane o giù di lì. –

+0

Questo lo farebbe, si. :) –