Co robi ArrayIndexOutOfBoundsException
znaczy i jak się go pozbyć?
Oto przykładowy kod, który wyzwala wyjątek:
String[] names = { "tom", "bob", "harry" };
for (int i = 0; i <= names.length; i++) {
System.out.println(names[i]);
}
Co robi ArrayIndexOutOfBoundsException
znaczy i jak się go pozbyć?
Oto przykładowy kod, który wyzwala wyjątek:
String[] names = { "tom", "bob", "harry" };
for (int i = 0; i <= names.length; i++) {
System.out.println(names[i]);
}
i <= name.length
zi < name.length
- lub lepiej napisać zwiększona do pętli. (for (String aName : name) { ... }
)Odpowiedzi:
Pierwszym portem zawinięcia powinna być dokumentacja, która wyjaśnia to dość wyraźnie:
Na przykład:
Co do tego, jak tego uniknąć ... nie rób tego. Uważaj na indeksy tablic.
Jednym z problemów, na który natrafiają ludzie, jest myślenie, że tablice mają indeks 1, np
Spowoduje to pominięcie pierwszego elementu (indeks 0) i wyrzuci wyjątek, gdy indeks wynosi 5. Prawidłowe tutaj indeksy to 0-4 włącznie. Prawidłowe, idiomatyczne
for
stwierdzenie brzmi :(Zakładając, że potrzebujesz indeksu, oczywiście. Jeśli zamiast tego możesz użyć rozszerzonej pętli for, zrób to.)
źródło
for (int nestedIndex = 0; nestedIndex < array[outerIndex].length; nestedIndex++) { ... array[outerIndex][nestedIndex] ... }
.Zobacz też:
Aktualizacja : zgodnie z fragmentem kodu,
Indeks zawiera długość tablicy. To jest poza zasięgiem. Trzeba zastąpić
<=
przez<
.źródło
Z tego doskonałego artykułu: ArrayIndexOutOfBoundsException in for loop
Krótko mówiąc:
W ostatniej iteracji
i
będzie równyname.length
co jest niedozwolonym indeksem, ponieważ indeksy tablicowe są zerowe.Twój kod powinien przeczytać
źródło
Oznacza to, że próbujesz uzyskać dostęp do indeksu tablicy, który jest niepoprawny, ponieważ nie znajduje się między granicami.
Na przykład zainicjowałoby to pierwotną tablicę liczb całkowitych z górną granicą 4.
Programiści liczą od zera. Na przykład wyrzuciłoby to,
ArrayIndexOutOfBoundsException
ponieważ górna granica wynosi 4, a nie 5.źródło
Aby uniknąć wyjątku poza zakresem indeksu tablicy, należy użyć instrukcji rozszerzonej
for
gdzie i kiedy mogą.Podstawowa motywacja (i przypadek użycia) ma miejsce podczas iteracji i nie wymaga żadnych skomplikowanych kroków iteracji. Byś nie być w stanie korzystać z enhanced-
for
aby przesunąć wstecz w tablicy lub tylko iterate na każdym innym elemencie.Gwarantujesz, że nie zabraknie Ci elementów do iteracji, a Twój [poprawiony] przykład można łatwo przekonwertować.
Kod poniżej:
... odpowiada temu:
źródło
Co jest przyczyną
ArrayIndexOutOfBoundsException
?Jeśli myślisz o zmiennej jako „polu”, w którym możesz umieścić wartość, to tablica to seria pól umieszczonych obok siebie, gdzie liczba pól jest skończoną i jawną liczbą całkowitą.
Tworzenie takiej tablicy:
tworzy rząd 5 pól, każde z nich zawiera
int
. Każde z pól ma indeks, pozycję w szeregu pól. Indeks zaczyna się od 0, a kończy na N-1, gdzie N jest rozmiarem tablicy (liczba pól).Aby pobrać jedną z wartości z tej serii pól, możesz odwołać się do niej poprzez jej indeks, jak poniżej:
Który da ci wartość czwartego pola w serii (ponieważ pierwsze pole ma indeks 0).
Na
ArrayIndexOutOfBoundsException
to spowodowane próbą odzyskania „nieistniejącego” pola, przekazaniem indeksu wyższego niż indeks ostatniego „pola” lub ujemnego.W moim działającym przykładzie te fragmenty kodu spowodowałyby taki wyjątek:
Jak ominąć
ArrayIndexOutOfBoundsException
Aby temu zapobiec
ArrayIndexOutOfBoundsException
, należy wziąć pod uwagę kilka kluczowych punktów:Pętla
Przechodząc przez tablicę, zawsze upewnij się, że indeks, który pobierasz, jest ściśle mniejszy niż długość tablicy (liczba pól). Na przykład:
Zauważ, że
<
nigdy=
tam nie mieszaj …Możesz mieć ochotę zrobić coś takiego:
Po prostu nie. Trzymaj się powyższego (jeśli musisz użyć indeksu), a zaoszczędzi ci to dużo bólu.
Gdzie to możliwe, użyj foreach:
W ten sposób nie będziesz musiał w ogóle myśleć o indeksach.
Podczas wykonywania pętli, cokolwiek robisz, NIGDY nie zmieniaj wartości iteratora pętli (tutaj:
i
. Jedynym miejscem, w którym powinna to zmienić wartość, jest utrzymanie pętli. Zmiana go w inny sposób ryzykuje wyjątek i w większości przypadków nie jest konieczna.Pobieranie / aktualizacja
Podczas pobierania dowolnego elementu tablicy zawsze sprawdzaj, czy jest to prawidłowy indeks względem długości tablicy:
źródło
W swoim kodzie uzyskałeś dostęp do elementów od indeksu 0 do długości tablicy łańcuchów.
name.length
podaje liczbę obiektów łańcuchowych w tablicy obiektów łańcuchowych, tj. 3, ale można uzyskać dostęp tylko do indeksu 2name[2]
, ponieważ do tablicy można uzyskać dostęp od indeksu 0 doname.length - 1
miejsca, w którym otrzymujeszname.length
liczbę obiektów.Nawet podczas korzystania z
for
pętli zacząłeś od indeksu zero i powinieneś go zakończyćname.length - 1
. W tablicy [n] możesz uzyskać dostęp od [0] do [n-1].Na przykład:
W Twoim przypadku:
źródło
Dla podanej tablicy długość tablicy wynosi 3 (tj. Name.length = 3). Ale ponieważ przechowuje element zaczynający się od indeksu 0, ma maksymalny indeks 2.
Dlatego zamiast „i ** <= name.length” należy napisać „i <** name.length”, aby uniknąć „ArrayIndexOutOfBoundsException”.
źródło
Tyle o tym prostym pytaniu, ale chciałem tylko podkreślić nową funkcję w Javie, która pozwoli uniknąć nieporozumień związanych z indeksowaniem tablic nawet dla początkujących. Java-8 wyodrębniła dla ciebie zadanie iteracji.
Jaka jest korzyść? Cóż, jedna rzecz to czytelność jak angielski. Po drugie, nie musisz się martwić o
ArrayIndexOutOfBoundsException
źródło
Dostajesz z
ArrayIndexOutOfBoundsException
powodui<=name.length
części.name.length
zwraca długość ciąguname
, który wynosi 3. Stąd, gdy próbujesz uzyskać dostępname[3]
, jest to nielegalne i zgłasza wyjątek.Rozwiązany kod:
Jest zdefiniowany w specyfikacji języka Java :
źródło
Tak wygląda ten typ wyjątku, gdy zostanie zgłoszony w Eclipse. Liczba na czerwono oznacza indeks, do którego próbowano uzyskać dostęp. Więc kod wyglądałby tak:
Błąd jest zgłaszany podczas próby uzyskania dostępu do indeksu, który nie istnieje w tej tablicy. Jeśli tablica ma długość 3,
jedynymi poprawnymi indeksami są:
Jeśli tablica ma długość 1,
wówczas jedynym poprawnym indeksem jest:
Każda liczba całkowita równa długości tablicy lub większa niż to: jest poza zakresem.
Każda liczba całkowita mniejsza niż 0: jest poza zakresem;
PS: Jeśli chcesz lepiej zrozumieć tablice i wykonać kilka praktycznych ćwiczeń, tutaj jest wideo: samouczek na temat tablic w Javie
źródło
W przypadku tablic wielowymiarowych uzyskanie dostępu do
length
właściwości odpowiedniego wymiaru może być trudne . Weźmy na przykład następujący kod:Każdy wymiar ma inną długość, więc subtelny błąd polega na tym, że środkowa i wewnętrzna pętla używają
length
właściwości tego samego wymiaru (ponieważa[i].length
jest taki sam jaka[j].length
).Zamiast tego należy użyć pętli wewnętrznej
a[i][j].length
(luba[0][0].length
, dla uproszczenia).źródło
Najczęstszym przypadkiem, jaki widziałem dla pozornie tajemniczych ArrayIndexOutOfBoundsExceptions, tj. Najwyraźniej nie spowodowanych własnym kodem obsługi tablicy, jest równoczesne użycie SimpleDateFormat. W szczególności w serwletie lub kontrolerze:
Jeśli dwa wątki wprowadzą razem metodę SimplateDateFormat.parse (), prawdopodobnie zobaczysz wyjątek ArrayIndexOutOfBoundsException. Zwróć uwagę na sekcję synchronizacji klasy javadoc dla SimpleDateFormat .
Upewnij się, że w kodzie nie ma miejsca, które ma dostęp do niebezpiecznych klas wątków, takich jak SimpleDateFormat, w sposób równoczesny, np. W serwletie lub kontrolerze. Sprawdź wszystkie zmienne instancji serwletów i kontrolerów pod kątem prawdopodobnych podejrzanych.
źródło
ArrayIndexOutOfBoundsException za każdym razem, gdy nadchodzi ten wyjątek, oznacza to, że próbujesz użyć indeksu tablicy, który jest poza jego granicami lub, w kategoriach laików, żądasz więcej niż zainicjowałeś.
Aby temu zapobiec, zawsze upewnij się, że nie żądasz indeksu, który nie jest obecny w tablicy, tj. Jeśli długość tablicy wynosi 10, wówczas twój indeks musi zawierać się w przedziale od 0 do 9
źródło
ArrayIndexOutOfBounds oznacza, że próbujesz zaindeksować pozycję w tablicy, która nie jest przydzielona.
W tym przypadku:
Aby obejść ten problem ...
W swojej pętli for możesz zrobić i <name.length. Zapobiegnie to zapętleniu nazwy [3], a zamiast tego zatrzyma się przy nazwie [2]
for(int i = 0; i<name.length; i++)
Użyj a dla każdej pętli
String[] name = { "tom", "dick", "harry" }; for(String n : name) { System.out.println(n); }
Użyj list.forEach (akcja konsumenta) (wymaga Java8)
String[] name = { "tom", "dick", "harry" }; Arrays.asList(name).forEach(System.out::println);
Konwertuj tablicę na strumień - jest to dobra opcja, jeśli chcesz wykonywać dodatkowe „operacje” na tablicy, np. Filtrować, przekształcać tekst, konwertować na mapę itp. (Wymaga Java8)
String[] name = { "tom", "dick", "harry" }; --- Arrays.asList(name).stream().forEach(System.out::println); --- Stream.of(name).forEach(System.out::println);
źródło
ArrayIndexOutOfBoundsException
oznacza, że próbujesz uzyskać dostęp do indeksu tablicy, który nie istnieje lub jest poza jej granicami. Indeksy tablic zaczynają się od 0 i kończą na długości - 1 .W Twoim przypadku
ArrayIndexOutOfBoundsException
zdarza się, gdy próbujesz uzyskać dostęp do elementu indeksowanego name.length, który nie istnieje (indeks tablicy kończy się na długości -1). samo zastąpienie <= na <rozwiązałoby ten problem.źródło
Dla dowolnej tablicy o długości n elementy tablicy będą miały indeks od 0 do n-1.
Jeśli twój program próbuje uzyskać dostęp do dowolnego elementu (lub pamięci) o indeksie tablic większym niż n-1, wówczas Java zgłosi wyjątek ArrayIndexOutOfBoundsException
Oto dwa rozwiązania, które możemy wykorzystać w programie
Utrzymanie liczby:
Lub jakieś inne zdanie zapętlające się jak
Lepszym rozwiązaniem jest użycie dla każdej pętli, w tej metodzie programista nie musi zawracać sobie głowy liczbą elementów w tablicy.
źródło
Zgodnie z Twoim kodeksem:
Jeśli zaznaczysz System.out.print (name.length);
dostaniesz 3;
oznacza to, że twoje imię to 3
twoja pętla działa od 0 do 3, która powinna być „0 do 2” lub „1 do 3”
Odpowiedź
źródło
Każdy element w tablicy jest nazywany elementem, a do każdego elementu można uzyskać dostęp za pomocą indeksu liczbowego. Jak pokazano na poprzedniej ilustracji, numeracja zaczyna się od 0 . Na przykład, dziewiąty element byłby zatem dostępny pod indeksem 8.
IndexOutOfBoundsException jest zgłaszany, aby wskazać, że jakiś indeks (taki jak tablica, ciąg lub wektor) jest poza zakresem.
Dostęp do dowolnej tablicy X można uzyskać od [0 do (X.length - 1)]
źródło
Widzę tutaj wszystkie odpowiedzi wyjaśniające, jak pracować z tablicami i jak unikać indeksu poza wyjątkami. Osobiście unikam tablic za wszelką cenę. Korzystam z klas Kolekcje, co pozwala uniknąć wszelkich głupot związanych z całkowitym radzeniem sobie z indeksami tablic. Zapętlone konstrukcje wspaniale działają z kolekcjami obsługującymi kod, który jest zarówno łatwiejszy do pisania, zrozumienia, jak i utrzymania.
źródło
Jeśli używasz długości tablicy do kontrolowania iteracji pętli for , zawsze pamiętaj, że indeks pierwszego elementu w tablicy wynosi 0 . Zatem indeks ostatniego elementu w tablicy jest o jeden mniejszy niż długość tablicy.
źródło
ArrayIndexOutOfBoundsException
sama nazwa wyjaśnia, że jeśli próbujesz uzyskać dostęp do wartości w indeksie, który jest poza zakresem rozmiaru tablicy, wystąpi tego rodzaju wyjątek.W twoim przypadku możesz po prostu usunąć znak równości z pętli for.
Lepszą opcją jest iteracja tablicy:
źródło
Ten błąd występuje w czasach przekroczenia limitu pętli uruchomień. Rozważmy prosty przykład taki jak ten:
Na początku zainicjowałem tablicę jako „numberArray”. następnie niektóre elementy tablicy są drukowane przy użyciu pętli for. Gdy pętla działa w trybie „i”, wydrukuj element (liczbaArray [i + 1] .. (gdy wartość i wynosi 1, drukowany jest element numberArray [i + 1]). Załóżmy, że gdy i = (liczbaArray. length-2), wypisywany jest ostatni element tablicy. Gdy wartość „i” idzie do (numberArray.length-1), nie ma wartości do drukowania .. W tym momencie występuje „ArrayIndexOutOfBoundsException”. Mam nadzieję, że uda ci się uzyskać pomysł. dziękuję!
źródło
Możesz użyć Opcjonalnie w funkcjonalnym stylu, aby uniknąć
NullPointerException
iArrayIndexOutOfBoundsException
:Wynik:
źródło
Nie można iterować ani przechowywać większej liczby danych niż długość tablicy. W takim przypadku możesz wykonać następujące czynności:
Albo to:
źródło