2015-12-18 21 views
5

Gli oggetti vengono creati solo quando viene utilizzata la parola chiave new? Quanti oggetti sono stati creati una volta che questo codice raggiunge i commenti? Sto dicendo 4 nuovi oggetti perché il costruttore chiama new Exception() ogni volta che viene inizializzato un Car. Come posso verificare il numero di oggetti creati?Determinare il numero di oggetti creati in Java

class Car { 
    Car() { 
     try { 
      throw new Exception(); 
     } catch (Exception ex) { 
      System.out.println("Do Nothing"); 
     } 
    } 
} 

class Test { 
    public static void main(String[] args) { 
     Car carOne = new Car(); 
     Car carTwo = new Car(); 
     Car carThree = carTwo; 
     // how many objects have been created? 4? 
    } 
} 
+2

È questo compito? Ho visto questo sugli esami prima ... –

+3

'new' non è l'unico modo per creare oggetti e quindi non è un contatore affidabile: http://stackoverflow.com/questions/95419/what-are-all -la-diversi-modi-per-creare-un-oggetto-in-java Nel tuo caso funziona, sì, qui vengono creati 4 oggetti. – MC10

+0

L'eccezione creerà probabilmente una traccia di stack internamente, che potrebbe creare un numero arbitrario di elementi di traccia stack ... –

risposta

8

Non v'è (almeno non a mia conoscenza) modo automatizzato di contare quanti oggetti sono stati creati in Java. Nel tuo esempio, tuttavia, vengono creati 4 oggetti, 2 eccezioni e due auto.

Se si desidera contare quanti oggetti sono per una determinata classe, è possibile avere un contatore statico che viene incrementato ogni volta che viene creato un oggetto.

Edit: potete contare gli oggetti creati utilizzando jmap, come sottolineato da Andreas, anche se si tratta di una soluzione non molto pratica

+0

È possibile modificare * la macchina virtuale Java * per contare il numero di operazioni malloc, ecc. –

+2

@CommuSoft È possibile ricreare l'universo per cuocere una torta di mele ...: D –

+1

L'aggiornamento della Macchina Virtuale si chiama AspectJ o qualcosa del genere. –

3

È possibile utilizzare jmap e jhat per ottenere un dump di memoria della JVM.

Aggiunta di un Thread.sleep(20000) al commento, il programma attenderà 20 secondi per l'esecuzione dei seguenti comandi. Aumentare il tempo di attesa, se necessario.

In un prompt dei comandi, eseguire il programma:

java -cp . Car 

In un prompt dei comandi diversa, durante la la 20 secondi di attesa, eseguire

jps 
jmap -dump:file=C:/temp/x.dmp 99999 
jhat C:/temp/x.dmp 

Dove 99999 è l'ID processo indicato nella uscita da jps.

Il programma jhat avvia un server web sulla porta 7000, in modo da andare a:

http://localhost:7000/ 

Cliccare su "Mostra esempio conta per tutte le classi (esclusi piattaforma)", e vedrete solo 2 oggetti:

2 instances of class Car 

Questo è perché escluso la classe Exception dalla visualizzazione.

Se si è fatto clic sul "... (compresa la piattaforma)" di collegamento, che si vede un sacco di oggetti, con qualcosa di simile:

Total of 6214 instances occupying 8071681 bytes. 

Se si implementa la propria eccezione, e.q. CarException e un tiro che, invece, vedrete 4 oggetti "utente" creati:

2 instances of class Car 
2 instances of class CarException 

Quindi, che la risposta è corretta? 2, 4 o 6214?
Probabilmente la risposta prevista è 4, come in "Quanti oggetti ha creato il tuo programma?".


Per quanto riguarda la questione di sapere se gli oggetti vengono creati solo quando si utilizza la parola chiave new, la risposta è No . Ci sono molti altri modi (ad esempio elencati in questa risposta: https://stackoverflow.com/a/2103578/5221149), e qui ci sono alcuni, con il commento per numero di oggetti creati dal costrutto:

// Using "new" 
new MyObject()  // 1 + number of objects created by constructor 
new int[0]   // 1 
new int[10]   // 1 
new int[] {1,2,3,4} // 1 
new int[10][]  // 1 
new int[10][20]  // 11 (1 outer array + 10 inner arrays) 

// Not using "new" 
int[] x = {1,2,3,4} // 1 
Integer x = 1  // 1 <-- autoboxing 
printf("", i, j) // 3 (autobox of i + autobox of j + varargs array) 
String x = "a" + i // 3 (StringBuilder + String + array backing String) 
Integer[][] x = {{1111},{2222},{3333,4444},{},{}} // 10 (1 outer array + 5 inner arrays + 4 Integers) 
Problemi correlati