2016-01-14 10 views
25

Wiem, że podobne pytania były zadawane kilka razy i były ładnie odpowiedział, ale ... oni o zerowej długości tablica 1 wymiar jak:Zero długość wielowymiarowa tablica

int[] array = new int[0]; 

Wydaje się, że nie jest celem dla takich tablic w przypadku, gdy nie należy/nie można użyć wartości zerowej. Ale dlaczego Java pozwala na tworzenie takich rzeczy:

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

Oczywiście jak w prostym przypadku 1D mamy nic z takiej tablicy, jeśli staramy się iteracyjne albo coś i Pytam tylko dlatego, że wygląda niezwykle przykry dla mnie. :-) Ile pamięci zostało przydzielone dla takiego bezsensownego stworzenia?

+0

Czy Twoje pytanie * dlaczego jest dozwolone * lub * ile pamięci zostało przydzielone *? – Manu

+9

Twórcy piszą bezsensowny kod przez cały czas i nie jest możliwe wykrycie każdej bezsensownej kombinacji, którą może wymyślić programista. –

+3

Wygląda na to, że możesz również skompilować 'new int [-1]' z powodzeniem [ideone] (http://ideone.com/MtZLBs) (oczywiście jednak zawiedzie w czasie wykonywania). Wygląda to na rodzaj błędu, który może powodować narzędzie takie jak [podatne na błędy Google] (https://github.com/google/error-prone) (chociaż wygląda na to, że obecnie nie działa, może dlatego, że jest po prostu * zbyt * głupi). –

Odpowiedz

31

Jeśli chodzi o to, dlaczego Java pozwala na to - z punktu widzenia języka (a nie z pojęciami, które próbujesz wyrazić przy pomocy tego słowa), dlaczego w konkretnym przypadku ma to zabronić? Jeśli zezwalasz na tablicę o zerowej długości dowolnego typu, dlaczego konkretnie zabronisz macierzy o zerowej długości int[9]? Odrzucenie go wymagałoby więcej sprawdzeń kompilatora w celu wymuszenia reguły, która jest w zasadzie bezużyteczna, ponieważ nawet bez reguły zachowanie jest dobrze zdefiniowane.

Dolna linia, kontrole kompilatora nie są tutaj, aby zapewnić, że twój program ma sens. Są tutaj tylko po to, by sprawdzić, czy są jednoznaczne.


Edited by dodać:

Jak wskazano w uwagach, takie sprawdzenie nie jest nawet bardzo możliwe, ponieważ długość tablicy nie jest częścią informacji typu i może być podawana w czasie wykonywania. Tak więc, oprócz "specjalnego przypadku", gdy istnieje int[0] bezpośrednio w kodzie źródłowym, kompilator nie ma nawet żadnych środków, aby wiedzieć, czy jest to tablica o zerowej długości.

+0

Jest to tablica o zerowej długości 'int []'. Rozmiar nie jest częścią typu w Javie. – immibis

+0

Należy również zauważyć, że jest to szczególny przypadek szczególnego przypadku. Wymiar nie musi być stały w Javie, dlatego zawsze istnieje sposób przekazania dokładnie tych liczb do wyrażenia tworzenia tablicy bez możliwości przewidzenia tego przez kompilator. A z wartościami dynamicznymi ta kombinacja może mieć sens w kontekście. – Holger

+0

@Holger dobry punkt, zredagowałem odpowiedź. To ładnie ilustruje, dlaczego kontrola jest nie tylko niepraktyczna, ale często niemożliwa. –

23

Spowoduje to utworzenie 6 obiektów - 5 pustych tablic i tablicę zawierającą te tablice.

Dlaczego jest dozwolone? Z tego samego powodu, co w przypadku tablic jednowymiarowych. Jeśli utworzyć tablicę takiego:

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

gdzie każdy p, q i r może być czasami 0, obsługi tych szczególnych przypadkach byłoby bardzo trudne. Zamiast tego otrzymujesz legalny obiekt, który może być użyty w pętli (bardzo krótka pętla - ta, która kończy się natychmiast, ale bez błędów).

+1

Twój punkt unikania unikania specjalnych przypadków jest dobry. Opiekunowie wielu standardów językowych zdają się przyjmować postawę, że jeśli wykonanie jakiegoś konstruktu w konkretnym przypadku nie byłoby użyteczne, nie ma powodu, aby go wspierać, nawet jeśli pozwoliłoby to na użyteczne uogólnienie, więc lubię widzieć przykłady miejsc, w których pozwolono takie uogólnienia są użyteczne. Przykładem języka, który denerwująco uniemożliwia takie użycie, jest C99; pozwala na zadeklarowanie tablic o rozmiarze obliczonym w środowisku wykonawczym, ale deklarowanie tablicy o zerowym rozmiarze wywołuje niezdefiniowane zachowanie, nawet jeśli kod ... – supercat

+0

... nigdy nie podejmuje żadnej próby uzyskania do niego dostępu (np. cały dostęp do tablicy jest włączony) pętla 'for', której ciało nigdy nie zostanie wykonane, jeśli rozmiar jest zerowy), a niezdefiniowane zachowanie w C jest gorsze niż wszystko, co istnieje w Javie, ponieważ pozwala kompilatorom wyrzucić z okna wszystkie pojęcia czasu i przyczynowości. – supercat

8

[5] rzeczywiście robi coś pożytecznego: Tablica oddalonych będą mieć tablice pięć element o długości 0.

Ale masz rację o [9]. Nic nie robi: Ponieważ wszystkie z pięciu pośrednich tablic będą puste, nie zostanie utworzona tablica o długości 9. Każda liczba całkowita może być umieszczona tam dokładnie taki sam efekt.

Język może być zaprojektowany w taki sposób, że gdyby była na jednym poziomie z zagnieżdżonej tablicy wymiar ustawiony dosłownym 0, wszystkie kolejne poziomy musiałby być ustawiony dosłownym 0 również. To jednak stworzy kolejny szczególny przypadek w specyfikacji i wdrożeniu, a korzyść będzie bardzo niewielka.

+5

"[9]" może rzeczywiście służyć celowi. Może nie funkcjonalny, ale semantyczny: Oznacza to, że trzeci wymiar tablicy * powinien * mieć długość 9, co może być przydatne, jeśli planujesz dodać elementy, aby drugi wymiar przestał być pusty. – Darkhogg

+0

@ Darkhogg Nie można zmienić rozmiaru tablicy Javy po utworzeniu instancji –

+1

@ Max? Możesz zamienić puste tablice na niepuste. – Darkhogg

Powiązane problemy