Oracle Java Foundations study materials
Oracle Java Foundations study resources

Telemetry Arrays: Aliases, Failed Resets and a Bad Lookup

Oracle Java Foundations · Put your knowledge to work in context.

All case studies

Telemetry Arrays: Aliases, Failed Resets and a Bad Lookup

A monitoring class holds a six-element int[] telemetry. Two helpers exist: bump(int[] a) does a[0]++, and reset(int[] a) does a = new int[a.length]. After bump(readings) the caller's first element changed; after reset(readings) nothing changed. Elsewhere a developer wrote int[] copy = readings;, sorted copy with Arrays.sort, and the original array came back sorted too. A lookup then ran Arrays.binarySearch on an unsorted array and returned -3 for a value that was definitely present. In the same file, int[][] grid = new int[3][]; followed by grid[0][0] = 1; threw a NullPointerException.

1. Explain why `bump` alters the caller's array while `reset` does not, and give two ways to make `reset` actually clear the caller's data.

Read the worked answer

Java is pass-by-value for every argument. For an array, the value passed is a copy of the reference. bump receives that copy and dereferences it, so a[0]++ writes through the shared reference into the one array object the caller also sees. reset only rebinds its own parameter to a fresh array; the caller's variable still points at the original object, which is untouched. The parameter is a local variable.

To make it effective, either mutate the existing object in place:

Arrays.fill(a, 0);

or copy new contents into it, or return the new array and let the caller assign:

static int[] reset(int[] a) { return new int[a.length]; }
readings = reset(readings);

Returning without reassigning at the call site would have the same no-op effect.

2. Explain the sort aliasing bug and the -3 return from `binarySearch`, including what -3 conventionally encodes.

Read the worked answer

Aliasing: int[] copy = readings; copies the reference, not the elements. There is one array object with two names, so sorting copy sorts readings. Real copies require Arrays.copyOf(readings, readings.length), readings.clone(), or System.arraycopy.

Binary search: Arrays.binarySearch requires the array to be sorted in ascending order for the element type. On unsorted input the result is undefined - the algorithm may return a negative value for an element that is present, which is exactly what happened. The negative encoding is -(insertion point) - 1, so -3 means insertion point 2, i.e. 'would be inserted at index 2'. That value is only meaningful on a sorted array.

The correct sequence is: sort first (with Arrays.sort), then search. Caching a search result against a later-mutated array repeats the same mistake.

3. Why does `grid[0][0] = 1;` throw a NullPointerException after `new int[3][]`, and what are the two fixes?

Read the worked answer

new int[3][] allocates only the outer array: length 3, slots ready to hold int[] references. Those three slots are initialized to null, no inner arrays are created. grid[0] evaluates to null, so grid[0][0] = 1 dereferences null and throws NullPointerException. Note that grid.length is 3 under either declaration, so a length check on grid will not catch the problem.

Fixes:

int[][] grid = new int[3][4];        // rectangular: all rows allocated
// or jagged: allocate each row explicitly
int[][] jagged = new int[3][];
jagged[0] = new int[4];

A jagged declaration requires an allocation per row before use; relying on the outer new alone is the bug.