2016-01-14 19 views
25

so che simili questioni sono state poste diverse volte e sono stati ben risposto, ma ... erano circa zero gamma lunghezza di 1 dimensione come:Zero lunghezza multidimensionale matrice

int[] array = new int[0]; 

sembra che ci sia uno scopo per tali matrici nel caso in cui null non dovrebbe/non può essere utilizzato. Ma perché Java consente di creare cose del genere:

int[][][] multiDims = new int[5][0][9]; 

Naturalmente come nel semplice caso 1D otteniamo nulla da tale varietà se cerchiamo di iterare o qualcosa del genere e mi chiedo solo perché appare estremamente sgradevole per me. :-) Quanta memoria è allocata per una creatura così inutile?

+0

La tua domanda * perché è consentito * o * quanta memoria è allocata *? – Manu

+9

Gli sviluppatori scrivono sempre codice senza senso e non è possibile rilevare ogni combinazione inutile che uno sviluppatore può inventare. –

+3

Sembrerebbe che tu possa compilare anche 'new int [-1]' con successo [ideone] (http://ideone.com/MtZLBs) (ovviamente fallisce in fase di runtime, comunque). Questo sembra il tipo di errore che strumenti come [Google's error-prono] (https://github.com/google/error-prone) potrebbero decidere di catturare (anche se sembra che non sia al momento, forse perché è solo * troppo * sciocco). –

risposta

31

Per quanto riguarda il motivo per cui Java consente questo - dal punto di vista del linguaggio (non i concetti che si sta tentando di esprimere con esso), perché dovrebbe specificamente impedirlo? Se si consente un array di lunghezza zero di qualsiasi tipo, perché non consentire specificamente un array a lunghezza zero di int[9]? Disabilitarlo richiederebbe più controlli del compilatore per imporre una regola che è fondamentalmente inutile, perché anche senza la regola il comportamento è ben definito.

In fondo, i controlli del compilatore non sono qui per garantire che il programma abbia senso. Sono qui solo per verificare che non sia ambiguo.


cura di aggiungere:

Come sottolineato in osservazioni, tale controllo non è ancora veramente possibile, in quanto la lunghezza di matrice non è parte delle informazioni tipo e può essere somministrato in fase di esecuzione. Quindi, a parte un "caso speciale" quando c'è int[0] direttamente nel codice sorgente, il compilatore non ha nemmeno i mezzi per sapere se si tratta di un array a lunghezza zero.

+0

È una matrice a lunghezza zero di 'int []'. La dimensione non fa parte del tipo in Java. – immibis

+0

Va anche notato che questo è il caso speciale di un caso speciale. La dimensione non ha bisogno di essere costanti in Java, quindi, c'è sempre un modo per passare esattamente questi numeri a un'espressione di creazione dell'array senza che il compilatore sia in grado di prevederlo. E con valori dinamici, questa combinazione può avere senso nel contesto. – Holger

+0

@Holger buon punto, ho modificato la risposta. Ciò dimostra bene perché il controllo non è solo impraticabile ma anche spesso impossibile. –

23

Questo creerà 6 oggetti: 5 array vuoti e un array contenente questi array.

Perché è consentito? Per la stessa ragione come nel caso degli array monodimensionali. Se si crea un array come questo:

int[][][] multiDims = new int[p][q][r]; 

dove ogni p, q e r può essere a volte 0, trattare questi casi particolari sarebbe molto difficile. Invece si ottiene un oggetto legittimo che può essere utilizzato in un ciclo (un ciclo molto breve - uno che termina immediatamente, ma senza errori).

+1

Il tuo punto evita di evitare il bisogno di casi speciali è buono. I manutentori di molti standard linguistici sembrano prendere l'idea che se l'esecuzione di alcuni costrutti in un caso specifico non servirebbe a nulla, non c'è motivo di supportarla, anche se consentirebbe un'utile generalizzazione, quindi mi piace vedere esempi di luoghi in cui permettere tali generalizzazioni sono utili. Un esempio di linguaggio che disapprova fastidiosamente tale utilizzo è C99; consente agli array di essere dichiarati con una dimensione calcolata in fase di esecuzione, ma dichiarare che un array a dimensione zero richiama il comportamento non definito anche se il codice ... – supercat

+0

... non fa mai alcun tentativo di accedervi effettivamente (ad es. tutto l'accesso all'array è in un ciclo 'for' il cui corpo non viene mai eseguito se la dimensione è zero), e il comportamento non definito in C è peggiore di qualsiasi cosa che esiste in Java, dal momento che consente ai compilatori di eliminare tutte le nozioni di tempo e di causalità dalla finestra. – supercat

8

Il [5] in realtà fa qualcosa di utile: La matrice più esterno avrà array di cinque elementi con lunghezza 0.

Ma hai ragione circa la [9]. Non fa nulla: poiché tutti i cinque array intermedi saranno vuoti, non verrà creata alcuna matrice di lunghezza 9. Qualsiasi numero intero potrebbe essere messo lì esattamente allo stesso effetto.

Il linguaggio avrebbe potuto essere progettato in modo che se ci fosse un livello di vettore annidato con dimensione impostata letterale 0, quindi tutti i livelli successivi dovrebbero essere impostati letterale 0 pure. Ma questo creerebbe ancora un altro caso speciale nelle specifiche e nell'implementazione e il beneficio sarebbe molto piccolo.

+5

Il '[9]' potrebbe effettivamente servire a uno scopo. Forse non uno funzionale, ma semantico: significa che la terza dimensione dell'array * dovrebbe * essere di lunghezza 9, che potrebbe essere utile se si intende aggiungere elementi in modo che la seconda dimensione smetta di essere vuota. – Darkhogg

+0

@Darkhogg Non è possibile ridimensionare un array Java dopo l'istanziazione –

+1

@Max così? È possibile scambiare gli array vuoti con quelli non vuoti. – Darkhogg

Problemi correlati