9

Kann mir jemand erklären, warum ArrayIndexOutOfBoundsException eine Laufzeit-Ausnahme anstelle eines Kompilierungsfehlers ist? In offensichtlichen Fällen, wenn die Indizes negativ oder größer als die Array-Größe sind, sehe ich nicht, warum es kein Fehler bei der Kompilierung sein kann.Warum hat die ArrayIndexOutOfBoundsException keinen Fehler bei der Kompilierung?

Bearbeitet: vor allem, wenn die Größe des Arrays und sogar die Indizierung zur Kompilierzeit bekannt ist, zum Beispiel int[] a = new int[10]; a[-1]=5; Dies sollte ein Kompilierungsfehler sein.

+2

Während Sie offensichtliche Beispiele herausziehen können, die ein Compiler fangen konnte, sind sie nicht die übliche Ursache; es ist die sneeky diejenigen, die Sie bekommen. Ich habe nie 'a [-1] = 5;' oder ähnlich getippt. Die 1-zu-große for-Schleife über ein Array ist ziemlich üblich für Leute, die anfangen (besonders wenn sie aus einer 1-indexierten Sprache kommen) und es wäre nett, wenn das abgefangen würde, aber dann beginnt der Compiler Teile zu laufen des Codes, um etwas zu fangen, das nur Anfängerprogramme tun. Alles kostet Zeit in der Compile-Stufe –

+0

Ich stimme zu, dass es gut ist, dass der Compiler keine for-Schleifen bezüglich der Array-Indizierung prüft ... aber immer noch a [-1] = 5; sollte ein Kompilierungsfehler sein, wie ein [1.5] = 5; wenn wir Dezimalzahlen verwenden. Ich wette, keiner von uns verwendet Dezimalzahlen als Index und es ist immer noch keine Ausnahme. –

Antwort

0

Beim Arbeiten mit Zeigern ist es möglich, negative Indizes zu haben und keinen Fehler zu haben, wenn Sie die Speicherposition, auf die Sie zugreifen, richtig reserviert haben. Hier ist ein Beispiel. Bei der Arbeit mit Low-Level-Programmiersprachen sind Dinge wie diese sehr häufig gemacht, aber sie haben wenig Sinn in Hochsprachen, zumindest für mich.

int arr[10]; 
int* p = &arr[2]; 

int x = p[-2]; // valid: accesses arr[0] 

, wenn Sie versuchen zu tun:

arr[-5] //you will access and invalid block of memory, this why you get the error. 

dies eine sehr hilfreiche führen und interessant:

http://www-ee.eng.hawaii.edu/~tep/EE160/Book/chap7/subsection2.1.3.2.html

+3

Diese und andere Antworten behandeln die Frage überhaupt nicht. Natürlich konnte der Compiler es in diesem Fall nicht abfangen; Die Frage ist, in einem Fall mit einer ** Konstante **, wo der Compiler ** sicher weiß, dass es eine Ausnahme auslösen wird, warum gibt es keinen Fehler bei der Kompilierung? – ajb

+1

Ihre Bearbeitung auf dem Post ist völlig irrelevant. Dies ist eine Java-Frage, keine C-Frage. – ajb

3

Da es nicht zur Compile-Zeit erkannt werden können alle die Zeit.

4

Die Größe der Arrays darf nur zur Laufzeit definiert werden (zum Beispiel im einfachsten Fall, wenn die Größe eines Arrays von der Benutzereingabe abhängt).

Daher wäre es unmöglich, zur Kompilierzeit für solche Ausnahmen zu überprüfen, indem man die Zugriffe eines Arrays überprüft, ohne seine Grenzen (Größe) zu kennen.

+0

Ich sehe, aber wenn die Größe zur Kompilierzeit definiert ist und sogar der Index zur Kompilierzeit negativ ist .... warum kann der Compiler dann keine Fehlermeldung erzeugen? –

0

Es gibt keine Möglichkeit, alle Indizes zur Kompilierzeit zu überprüfen, da es sich um Variablen handeln kann, deren Werte sich zur Laufzeit ändern können. Wenn Sie array[i] und i das Ergebnis des Lesens einer Datei haben, können Sie i auswerten, wenn Sie das Programm ausführen. Auch wenn Sie eine Variable verwenden, denken Sie daran, dass Sie Ihr Array neu zuweisen können, indem Sie seine Kapazität ändern. Dies kann wiederum nur zur Laufzeit überprüft werden. Weitere Informationen finden Sie unter Runtime vs Compile time.

0

Neben der Tatsache, dass Array-Größe kann nicht zur Kompilierzeit überprüft werden, möchte ich eine weitere Notiz über die Grenze der Größe eines Arrays hinzufügen, die im Bereich der primitiven int erwartet wird :

// This compiles, because the size evaluates to an integer. 
int[] array = new int[Integer.MAX_VALUE + 1]; 

// This doesn't compile. 
int[] array = new int[Long.MAX_VALUE]; 

Und dieser Fehler ist wegen length Feldes (int) von Arrays, die speziellen Java-Objekte sind.

1

Eingeben a[-1] = 5; ist etwas, was nur Neulinge tun würden (wie Richard Tingle sagte). Es lohnt sich also nicht, den Sprachstandard nur für diese Art von Fehlern zu aktualisieren. Ein interessanterer Fall wäre a[SOME_CONSTANT] = 5;, wobei SOME_CONSTANT als static final int SOME_CONSTANT = -1; (oder ein Ausdruck, der nur Konstanten enthält, die zu -1 berechnet werden) in einer anderen Klasse definiert ist. Aber auch dann, wenn der Compiler dies als einen Fehler markiert hat, kann es Fälle fangen, in denen der Programmierer a[SOME_CONSTANT] = 5; in eine if-Anweisung gesetzt hat, die bereits auf negative Werte der Konstante überprüft hat. (Ich gehe hier davon aus, dass SOME_CONSTANT eine Konstante ist, deren Wert sich ändern könnte, wenn sich die Anforderungen der Anwendung ändern.) Obwohl die Sprache es theoretisch unmöglich machen würde, eine Array-Indexierungsoperation zu schreiben, die unmöglich gelingen kann, gibt es gute Gründe, dies nicht zu tun.

P.S. Das ist ein echtes Problem. Die Ada-Sprache prüft einige Kompilierungszeit auf statische Ausdrücke, die nicht erfolgreich sein können, aber es prüft diesen Fall nicht, und es hat in den letzten paar Wochen einige Diskussionen darüber gegeben, ob es sollte, oder ob Compiler erlaubt sein sollten (aber nicht erforderlich), um Programme mit Array-Indizierung abzulehnen, von denen bekannt ist, dass sie fehlschlagen.