2015-09-20 17 views
7

My Background è C++ e in C++ possiamo facilmente creare array di oggetti usando una semplice sintassi. className obj[n]; e anche il costruttore chiamerà il tempo n.Matrice di oggetti in Java vs C++

Ma quando ho provato a creare array di oggetti in java className[] obj=new className[n]; nessuna chiamata del costruttore. Dopo la ricerca ho trovato la risposta di questa domanda su stackoverflow che è sufficiente creare n Riferimento che può puntare a n oggetti e ho bisogno di creare nuovamente oggetti per ogni riferimento come. obj[0]=new className();

Ora voglio solo chiedere perché java farlo? c'è qualche ragione anche se il C++ lo permette, ma java non permette di creare array di oggetti nello stesso modo? Ho cercato questo, ma non ho ancora ottenuto risposta esatta.

risposta

9

In C++ si ha la flessibilità di scegliere una memoria in cui si crea l'oggetto. È possibile creare oggetti nell'area automatica (in pila), nell'area statica o nell'area dinamica. Nell'ultimo caso ottieni un puntatore a oggetti e diventi responsabile di liberarlo dopo aver finito.

Al contrario, tutto ciò che Java ha è l'opzione di area dinamica, poiché tutti gli oggetti sono oggetti di riferimento. In C++ sarebbe equivalente all'utilizzo di oggetti solo tramite puntatori e creandoli sempre con new. Quando si esegue questa operazione in C++, si hanno anche per riempire il vostro array di puntatori con new oggetti -ed:

myclass *array[10]; 
for (int i = 0 ; i != 10 ; i++) { 
    array[i] = new myclass(); 
} 
... 
for (int i = 0 ; i != 10 ; i++) { 
    delete array[i]; 
} 

Permettere la creazione di array di oggetti in C++ è stata una scelta dettata dalla necessità di lasciare che i programmatori allocare array di oggetti in l'area automatica. È venuto con un compromesso, perché gli oggetti da cui si creano array devono avere costruttori predefiniti. Questo non è l'ideale, perché il requisito del costruttore predefinito suona arbitrario.

Java, d'altra parte, era esente dai requisiti di memoria automatica, quindi è andato per una soluzione semplice che richiede di inizializzare gli oggetti singolarmente.

2

Ciò che è consentito o non fare è compito dei progettisti del linguaggio.

Se si desidera inizializzare tutti gli elementi di un array con un riferimento allo stesso oggetto in Java è possibile utilizzare:

className[] obj = new clasName[2]; 
Arrays.fill(obj, new className()); 

o per creare oggetti diversi e passare argomenti diversi per ogni costruttore

className[] obj = new className[] {new className(), new className()};

+0

allora perché selezioniamo lingue diverse v'è motivo che ogni lingua abbia differenze di prestazioni, sicurezza ecc. e il progettista di ogni lingua seleziona sintassi/logica per una ragione Spiacente per i poveri inglese -_- –

+1

Nota che la soluzione 'Arrays.fill' creerà un oggetto e lo assegnerà a ogni elemento dell'array. Questo risultato è raramente previsto, in genere sono necessari oggetti distinti per ogni elemento dell'array. –

+0

grazie @TagirValeev ha modificato un Swer. –

3

Non molto spesso è necessario creare oggetti dello stesso tipo della matrice con il costruttore predefinito. A volte si desidera chiamare il costruttore personalizzato. A volte si desidera creare un'istanza delle sottoclassi e memorizzarle nell'array.

Si noti che l'array Java className[] obj è più equivalente all'array C++ className* obj[n], non solo className obj[n], perché è una matrice di riferimenti agli oggetti, non alla matrice di oggetti stessi. A partire da Java-8 non è possibile creare una matrice di oggetti stessi (sono discussi come parte di project Valhalla, ma non verranno visualizzati nemmeno in Java-9). Quando gli oggetti stessi sono archiviati nell'array in C++, è necessario inizializzare l'array con. Non è possibile mantenere "null" o qualcosa del genere lì, perché null non è un oggetto, è il riferimento (o puntatore). Quando si crea la matrice className* obj[n] in C++ (che è più simile alla matrice Java className[] obj), non è inizializzata.

Infine ricordiamo che in Java-8 è possibile creare facilmente tutti gli oggetti di loro istanziazione con costruttore di default in questo modo:

className[] array = Stream.generate(className::new).limit(n).toArray(className[]::new); 
+0

@Tiger se abbiamo bisogno di un po 'di tempo no-argu-constructor e talvolta di argu-constructor, allora perché creiamo riferimenti? possiamo creare oggetti quando abbiamo bisogno di un diverso costruttore. className obj = new className (5); 'o sometime' className obj2 = new className ("A"); 'Come mi aspetto Potrebbe essere solo per la leggibilità del codice e meno la codifica. C'è qualche altra ragione? (Scusa per un inglese scarso) –

+0

@Tagir Non è colpa tua, naturalmente, ma non andrei fino a chiamare la soluzione Java-8 "facile" –

+0

@LetDoit, mi spiace, non capisco la tua domanda. Prova a riformularlo. Se l'area commenti non è sufficiente, prendi in considerazione la pubblicazione di una nuova domanda aggiungendo tutti gli esempi necessari. –

1

In Java, ogni volta che si dichiara una variabile, sia esso un membro di un oggetto o una variabile locale, è di tipo primitivo (byte, char, ...) o di tipo di riferimento (puntatore a oggetto di qualche tipo).
Quindi, non ci sono matrici di oggetti, solo matrici di riferimenti.

In C++ si ha la libertà e la responsabilità di scegliere quanti indirections si fa, come allocare, libero, costruire e distruggere gli oggetti, l'aggiunta di complessità molto:

  • dereferenziare-operator (*pointer)
  • dereference-e-use-membro (pointer->member)
  • indirizzo-di-operatore (&object)
  • un modo per derivare un puntatore a tipo da altri tipi (type* var).
  • posizionamento nuovo (`new (puntatore) tipo (arg1, arg2);.?
  • esplicito delete-operator (delete pointer)
  • molto più