This page is open from a file path, so progress will not save. Serve the folder with a local web server and open it again. The command is in README.md.
Room 1 of 14
· about 30 minutes
Arrays as objects, and where their indices start
This is the first room of the unit, so it assumes nothing.
Tasks checked0 of 4XP earned on this path0
Room complete
What this room checks you can do
Student can state that a Java array is a single object holding a fixed-size sequence of same-typed values, and explain what each adjective rules out.
Notes
Fixed-size homogeneous sequence
An array is a single object that holds a fixed-size sequence of values of the same type. Two adjectives carry the weight: fixed-size means once you have constructed the array you cannot grow or shrink it (to "grow" you build a bigger one and copy), and homogeneous means every element has the same declared element type: int[] holds only int values, String[] holds only String references. The array itself is one object on the heap; the variable that names it holds a reference to that object.
This single-object property is why an array can be passed to a method, returned from a method, stored as a field, and aliased by another variable. The slots inside it are not separate variables: they are positions inside one object. That is the mental shift from loops, where every counter or accumulator was its own named variable.
final int[] temps = new int[5]; // one int[] object holding 5 int slots
temps[0] = 72; // fill the first slot
temps[1] = 68; // ... and so on
In other languages
Python:list is the closest analog but is dynamic (it can grow); the truly fixed-size typed counterpart is array.array('i', [0]*5) or numpy.zeros(5, dtype=int).
C:int temps[5]; is a fixed-size sequence on the stack; there is no "array object": just a contiguous run of bytes named by the identifier.
Kotlin:IntArray(5) is the homogeneous primitive-int counterpart; Array<Int> boxes each element.
Bounds and indices from zero
Java numbers array slots starting at 0. An array of length n has legal indices 0, 1, ..., n - 1. The first element is at index 0; the last element is at index n - 1, never n. The expression arr.length gives n, so arr[arr.length - 1] is the last element and arr[arr.length] is always out of bounds.
Zero-based indexing is inherited from C (where the index is literally an offset added to a base address). Java keeps the C numbering but adds a runtime guard: any attempt to use an index outside 0..length-1 throws ArrayIndexOutOfBoundsException instead of silently reading or writing neighboring memory. This is the most useful runtime check in CS1, because the off-by-one error it catches is the most common bug in array code.
Python: also zero-based; xs[-1] is a Python convenience for "last element" that Java does not provide.
C: zero-based, but no bounds check: xs[xs_len] reads whatever byte happens to live just past the array. This is the source of the buffer-overrun bugs that Java's bounds check prevents.
Kotlin: zero-based; throws ArrayIndexOutOfBoundsException like Java.
Buffer overrun history (and why Java bounds-checks)
Why does Java throw ArrayIndexOutOfBoundsException instead of just returning whatever lives at the bad address? Because the languages that do not throw an exception: C and C++: produced a generation of catastrophic security bugs called buffer overruns (or buffer overflows). Writing past the end of an array in C silently overwrites adjacent memory; if an attacker controls the data being written, they can overwrite a return address or a function pointer and take over the program. The 1988 Morris worm (the first internet worm), the 2001 Code Red worm, and the 2003 SQL Slammer worm all exploited this exact class of bug. Java was designed in the early 1990s with this history in mind, and bounds-checking arrays was a deliberate language-design decision: every read and write of arr[i] is preceded by a runtime check that 0 <= i < arr.length. C# (Microsoft, 2000) made the same choice for the same reason.
The message for CS1 is short. The exception is a gift. It tells you exactly where the bug is. In C, the same bug would silently corrupt your program and possibly create a security hole. When you see ArrayIndexOutOfBoundsException, you are seeing the runtime save you from a Morris-worm-class bug.
final int[] xs = new int[5];
xs[10] = 99; // Java: ArrayIndexOutOfBoundsException at runtime.
// C equivalent: silently writes into whatever memory follows xs.
In other languages
C: no bounds check. xs[10] = 99; writes into whatever memory follows the array: sometimes a local variable, sometimes a return address. This is the bug that Morris/Code Red/SQL Slammer exploited.
Python: bounds-checked; raises IndexError. Same philosophy as Java.
Rust: bounds-checked at runtime by default; the compiler can elide the check when bounds are statically provable.
Tasks
Do each one, then check the box. Checking a box is you saying you did it. You can uncheck a box if you check it by accident.
traceShow the answer
5.
traceShow the answer
0 through 6 inclusive.
traceShow the answer
ArrayIndexOutOfBoundsException is thrown; nothing is written.
traceShow the answer
no: last legal index is 4.
Self check
Type what you think the answer is. Getting it wrong costs nothing and you can try as many times as you want.
Given int[] a = new int[7];, predict the result of a[7].
throws ArrayIndexOutOfBoundsException.
Practice, untimed
Open this whenever you want, before the tasks or after them. Nothing in this section is recorded and nothing here is timed.
Declare and construct a double[] named prices with room for 10 values.writeShow the answer
final double[] prices = new double[10];.
Write an expression for the last element of an array xs of unknown length.writeShow the answer
xs[xs.length - 1].
Write an expression for the middle element of an odd-length array xs.writeShow the answer
xs[xs.length / 2] (integer division gives the middle slot for odd length).
Given the equivalent C code, predict what happens.traceShow the answer
writes into whatever memory follows the array (no exception, possibly silent corruption).
How this room finishes
This room is done when all 4 tasks are checked and the self check is answered.
What to do next
This line and the level under each idea above are worked out from what this browser has saved. Nothing is sent anywhere.