Java Language Specification — Arrays Source: https://docs.oracle.com/javase/specs/jls/se21/html/jls-10.html 1. Spec Reference JLS Chapter 10 : Arrays — https://docs.oracle.com/javase/specs/jls/se21/html/jls-10.html JLS §10.1 : Array Types JLS §10.2 : Array Variables JLS §10.3 : Array Creation JLS §10.4 : Array Access JLS §10.5 : Array Store Exception JLS §10.6 : Array Initializers JLS §10.7 : Array Members JLS §4.10.3 : Subtyping among Array Types JLS §15.10 : Array Creation and Access Expressions JLS §15.10.1 : Array Creation Expressions JLS §15.10.2 : Array Access Expressions JVMS §6 : newarray, anewarray, multianewarray instructions -- JLS §10.1: Array Types --
ArrayType:
PrimitiveType Dims
ClassOrInterfaceType Dims
TypeVariable Dims
Dims:
{Annotation} [ ] {{Annotation} [ ]}
-- JLS §15.10.1: Array Creation Expression --
ArrayCreationExpression:
new PrimitiveType DimExprs [Dims]
new ClassOrInterfaceType DimExprs [Dims]
new PrimitiveType Dims ArrayInitializer
new ClassOrInterfaceType Dims ArrayInitializer
DimExprs:
DimExpr {DimExpr}
DimExpr:
{Annotation} [ Expression ]
-- JLS §10.6: Array Initializers --
ArrayInitializer:
{ [VariableInitializerList] [,] }
VariableInitializerList:
VariableInitializer { , VariableInitializer }
VariableInitializer:
Expression
ArrayInitializer
-- JLS §15.10.2: Array Access Expression --
ArrayAccess:
ExpressionName [ Expression ]
PrimaryNoNewArray [ Expression ]
-- JLS §14.14.2: Enhanced for Statement (used with arrays) --
EnhancedForStatement:
for ( {VariableModifier} LocalVariableType VariableDeclaratorId :
Expression ) Statement
-- JLS §10.7: Array Members --
-- The members of an array type T[] are:
-- public final field length
-- public method clone(), overrides Object.clone()
-- All members inherited from class Object
3. Core Rules & Constraints 3.1 Array Creation Rules (JLS §10.3) Array creation allocates a new array object with a specified number of components. Component type determines default initialization (0, null, false, etc.). Length is always non-negative; negative length → NegativeArraySizeException. Length is fixed at creation; arrays are not resizable. The length field is a public final int — read-only. 3.2 Array Types (JLS §10.1) int[] is a distinct type from int[][], Integer[], int[][][], etc. Array types are reference types — arrays are objects on the heap. An array of type T[] stores components of type T. Multi-dimensional arrays are arrays of arrays: int[][] is an array of int[] references. 3.3 Array Access (JLS §10.4) Index must be int (or a type implicitly promotable to int: byte, short, char). long index is a compile error: arr[longIndex] — must cast to int. Valid indices: 0 to array.length - 1. Accessing index < 0 or >= length → ArrayIndexOutOfBoundsException. Access to null array → NullPointerException. 3.4 Array Store Exception (JLS §10.5) For reference arrays, the JVM checks that stored values are compatible with the actual component type. Storing wrong type → ArrayStoreException at runtime. This is a consequence of array covariance (JLS §4.10.3). 3.5 Array Covariance (JLS §4.10.3) If S is a subtype of T, then S[] is a subtype of T[]. This allows String[] to be assigned to Object[]. But storing a non-String into String[] via Object[] reference → ArrayStoreException. 3.6 Multi-Dimensional Arrays (JLS §10.3) new int[3][4] creates a 3-element array of int[4] arrays. new int[3][] creates a 3-element array of null int[] references (jagged array possible). Not required to be rectangular: int[][] rows can have different lengths. 4. Type Rules 4.1 Array Type Hierarchy (JLS §10.7) Every array type T[] is a subtype of: Object Cloneable java.io.Serializable Primitive array types (int[], double[], etc.) are NOT subtypes of each other, even if the primitives are related by widening. int[] is NOT a subtype of long[]. 4.2 Enhanced for Loop Types (JLS §14.14.2) Enhanced for works on: Arrays: iterates over each component. Iterable<T>: iterates using iterator(). For arrays, the loop variable type must be compatible with the component type. Widening is allowed: for (double d : intArray) is legal. 4.3 Array Initializer Types (JLS §10.6) An array initializer creates and initializes an array in one expression. The type of each element in { e1, e2, e3 } must be assignment-compatible with the component type. Trailing comma in initializer is legal: { 1, 2, 3, }. Array initializers without new keyword are only valid in declaration context or in another initializer. 4.4 Generic Arrays Cannot create arrays of generic types: new T[10] is a compile error for type parameter T. Cannot create arrays of parameterized types: new List<String>[10] is a compile error. new List<?>[10] is allowed (wildcard). Workaround: (T[]) new Object[10] — generates unchecked cast warning. 5. Behavioral Specification 5.1 Default Initialization (JLS §10.3, §4.12.5) When an array is created: | Component Type | Default Value | |----------------|---------------| | byte, short, int | 0 | | long | 0L | | float | 0.0f | | double | 0.0d | | char | '\u0000' | | boolean | false | | Reference types | null |
5.2 Array Copy Operations System.arraycopy(src, srcPos, dst, dstPos, length): native, most efficient array copy. Arrays.copyOf(original, newLength): creates new array, copies up to newLength elements. Arrays.copyOfRange(original, from, to): copies a range. Shallow copy only — nested reference arrays are not deep-copied. Object.clone() on arrays: returns a shallow copy. 5.3 Arrays Utility Class (java.util.Arrays) Method Description Arrays.sort(arr) Sorts in-place; uses dual-pivot quicksort (primitives), timsort (objects) Arrays.binarySearch(arr, key) Binary search in sorted array; result is undefined if not sorted Arrays.fill(arr, val) Fills all elements with val Arrays.equals(a, b) Element-by-element comparison Arrays.deepEquals(a, b) Deep comparison for multi-dimensional arrays Arrays.toString(arr) String representation like [1, 2, 3] Arrays.deepToString(arr) For nested arrays Arrays.asList(T... a) Fixed-size List backed by array Arrays.stream(arr) Returns a stream over the array Arrays.copyOf(arr, n) Copy with new length Arrays.copyOfRange(arr, from, to) Copy subrange
6. Defined vs Undefined Behavior Situation Behavior per JLS arr[-1] ArrayIndexOutOfBoundsException arr[arr.length] ArrayIndexOutOfBoundsException null[0] NullPointerException new int[-1] NegativeArraySizeException new int[0] Legal: zero-length array with length == 0 Storing wrong type in reference array ArrayStoreException at runtime int[] assigned to long[] Compile error (not covariant) String[] assigned to Object[] Legal at compile time (covariant) Arrays.binarySearch() on unsorted array Undefined result (no exception, wrong answer) arr.clone() for multidimensional array Shallow copy — inner arrays are shared
7. Edge Cases from Spec 7.1 Array Length Zero int [] empty = new int [ 0 ] ;
System . out . println ( empty . length ); // 0 — legal, not null
for ( int x : empty ) { // zero iterations — no error
System . out . println ( x );
}
7.2 Primitive Array Covariance Does NOT Exist int [] ints = { 1 , 2 , 3 };
// long[] longs = ints; // COMPILE ERROR: int[] is not a subtype of long[]
// Object[] objs = ints; // COMPILE ERROR: int[] is not a subtype of Object[]
Object obj = ints ; // OK: int[] IS a subtype of Object
7.3 ArrayStoreException String [] strings = new String [ 3 ] ;
Object [] objects = strings ; // widening reference
objects [ 0 ] = "hello" ; // OK: String into String[]
try {
objects [ 1 ] = new Integer ( 42 ); // ArrayStoreException: Integer, not String
} catch ( ArrayStoreException e ) {
System . out . println ( e . getMessage ());
}
7.4 Multidimensional Jagged Arrays int [][] triangle = new int [ 5 ][] ;
for ( int i = 0 ; i < triangle . length ; i ++ ) {
triangle [ i ] = new int [ i + 1 ] ; // row 0: length 1, row 1: length 2, etc.
}
System . out . println ( triangle [ 4 ] . length ); // 5
7.5 Array Clone is Shallow int [][] original = {{ 1 , 2 }, { 3 , 4 }};
int [][] cloned = original . clone (); // shallow copy
cloned [ 0 ][ 0 ] = 99 ; // modifies original[0][0] too!
System . out . println ( original [ 0 ][ 0 ] ); // 99
cloned [ 1 ] = new int [] { 5 , 6 }; // does NOT affect original[1]
System . out . println ( original [ 1 ][ 0 ] ); // 3
7.6 Generic Array Creation Workaround @SuppressWarnings ( "unchecked" )
< T > T [] createArray ( int size ) {
return ( T [] ) new Object [ size ] ; // unchecked cast — safe if T is not reified
}
8. Version History Java Version Change JEP/Reference Java 1.0 Arrays defined; length field; array types JLS 1st ed. Java 1.1 System.arraycopy() JDK 1.1 API Java 2 java.util.Arrays introduced (sort, binarySearch, fill, equals) JDK 1.2 Java 5 Enhanced for loop over arrays; varargs JSR 201 Java 5 Arrays.copyOf(), Arrays.copyOfRange(), Arrays.toString() JDK 5 API Java 6 Arrays.copyOf (actually 6) JDK 6 Java 8 Arrays.stream(), Arrays.parallelSort(), Arrays.parallelSetAll() JEP 103 Java 9 Arrays.mismatch() JDK 9 API Java 11 No major array changes — Java 21 No major array changes; sequenced collections affect array-list interop JEP 431
9. Implementation-Specific Behavior (JVM-Specific) 9.1 JVM Bytecode for Arrays Operation Bytecode new int[n] newarray T_INT new String[n] anewarray java/lang/String new int[m][n] multianewarray [[I 2 arr[i] (int[]) iaload arr[i] = v (int[]) iastore arr.length arraylength
9.2 Array Memory Layout Array header contains: class pointer, identity hash, array length. On HotSpot 64-bit with compressed oops: header = 16 bytes. int[] of length N: 16 + 4*N bytes (aligned to 8 bytes). Object[] of length N: 16 + 4N bytes (with compressed oops) or 16 + 8 N (without). 9.3 Arrays.sort Algorithms (HotSpot) Primitive arrays: dual-pivot quicksort (introduced Java 7) — O(n log n) average. Object arrays: timsort (merge of merge sort + insertion sort) — O(n log n) worst case, stable. Arrays.parallelSort(): parallel merge sort using ForkJoinPool — beneficial for large arrays. 9.4 System.arraycopy vs Manual Loop System.arraycopy uses JVM intrinsic — compiles to memmove/memcpy at JIT level. Significantly faster than a manual loop for large arrays. Handles overlapping source/destination correctly. 10. Spec Compliance Checklist 11. Official Examples (Compilable Java 21 Code) // Example 1: Array Fundamentals
// File: ArrayFundamentals.java
import java.util.Arrays ;
public class ArrayFundamentals {
public static void main ( String [] args ) {
// 1D primitive array
int [] numbers = new int [ 5 ] ; // default: all zeros
numbers [ 0 ] = 10 ;
numbers [ 1 ] = 20 ;
numbers [ 2 ] = 30 ;
System . out . println ( "Length: " + numbers . length ); // 5
System . out . println ( Arrays . toString ( numbers )); // [10, 20, 30, 0, 0]
// Array initializer
String [] fruits = { "apple" , "banana" , "cherry" };
System . out . println ( fruits [ 1 ] ); // banana
// Enhanced for loop
int sum = 0 ;
for ( int n : numbers ) {
sum += n ;
}
System . out . println ( "Sum: " + sum ); // 60
// Sorting
int [] unsorted = { 5 , 2 , 8 , 1 , 9 , 3 };
Arrays . sort ( unsorted );
System . out . println ( Arrays . toString ( unsorted )); // [1, 2, 3, 5, 8, 9]
// Binary search (on sorted array)
int idx = Arrays . binarySearch ( unsorted , 5 );
System . out . println ( "Index of 5: " + idx ); // 3
// Filling and copying
int [] filled = new int [ 5 ] ;
Arrays . fill ( filled , 42 );
System . out . println ( Arrays . toString ( filled )); // [42, 42, 42, 42, 42]
int [] copy = Arrays . copyOf ( numbers , 3 );
System . out . println ( Arrays . toString ( copy )); // [10, 20, 30]
}
}
// Example 2: Multi-Dimensional Arrays
// File: MultiDimensionalArrays.java
import java.util.Arrays ;
public class MultiDimensionalArrays {
public static void main ( String [] args ) {
// 2D rectangular array
int [][] matrix = new int [ 3 ][ 4 ] ;
for ( int i = 0 ; i < 3 ; i ++ ) {
for ( int j = 0 ; j < 4 ; j ++ ) {
matrix [ i ][ j ] = i * 4 + j ;
}
}
System . out . println ( Arrays . deepToString ( matrix ));
// [[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11]]
// 2D jagged array
int [][] triangle = new int [ 4 ][] ;
for ( int i = 0 ; i < 4 ; i ++ ) {
triangle [ i ] = new int [ i + 1 ] ;
Arrays . fill ( triangle [ i ] , i + 1 );
}
System . out . println ( Arrays . deepToString ( triangle ));
// [[1], [2, 2], [3, 3, 3], [4, 4, 4, 4]]
// Inline 2D initializer
int [][] grid = {
{ 1 , 2 , 3 },
{ 4 , 5 , 6 },
{ 7 , 8 , 9 }
};
System . out . println ( "Center: " + grid [ 1 ][ 1 ] ); // 5
// Matrix multiplication
int [][] a = {{ 1 , 2 }, { 3 , 4 }};
int [][] b = {{ 5 , 6 }, { 7 , 8 }};
int [][] result = multiply ( a , b );
System . out . println ( Arrays . deepToString ( result ));
// [[19, 22], [43, 50]]
}
static int [][] multiply ( int [][] a , int [][] b ) {
int n = a . length ;
int [][] result = new int [ n ][ n ] ;
for ( int i = 0 ; i < n ; i ++ )
for ( int j = 0 ; j < n ; j ++ )
for ( int k = 0 ; k < n ; k ++ )
result [ i ][ j ] += a [ i ][ k ] * b [ k ][ j ] ;
return result ;
}
}
// Example 3: Array Covariance and ArrayStoreException
// File: ArrayCovariance.java
public class ArrayCovariance {
public static void main ( String [] args ) {
// Legal widening (covariance)
String [] strings = { "hello" , "world" };
Object [] objects = strings ; // String[] is-a Object[]
// Safe write
objects [ 0 ] = "new value" ;
System . out . println ( strings [ 0 ] ); // new value
// ArrayStoreException: writing wrong type
try {
objects [ 1 ] = 42 ; // Integer is NOT a String
} catch ( ArrayStoreException e ) {
System . out . println ( "ArrayStoreException: " + e . getMessage ());
}
// Safe pattern: instanceof check
Object [] mixed = new Object [ 3 ] ;
mixed [ 0 ] = "hello" ;
mixed [ 1 ] = 42 ;
mixed [ 2 ] = 3.14 ;
for ( Object obj : mixed ) {
if ( obj instanceof String s ) {
System . out . println ( "String: " + s . toUpperCase ());
} else if ( obj instanceof Integer i ) {
System . out . println ( "Integer: " + ( i * 2 ));
}
}
}
}
// Example 4: Arrays and Streams (Java 8+)
// File: ArrayStreams.java
import java.util.Arrays ;
import java.util.stream.IntStream ;
public class ArrayStreams {
public static void main ( String [] args ) {
int [] numbers = { 5 , 3 , 8 , 1 , 9 , 2 , 7 , 4 , 6 };
// Stream operations on array
int sum = Arrays . stream ( numbers ). sum ();
System . out . println ( "Sum: " + sum ); // 45
double avg = Arrays . stream ( numbers ). average (). orElse ( 0 );
System . out . printf ( "Average: %.1f%n" , avg ); // 5.0
int max = Arrays . stream ( numbers ). max (). orElse ( 0 );
System . out . println ( "Max: " + max ); // 9
long count = Arrays . stream ( numbers ). filter ( n -> n > 5 ). count ();
System . out . println ( "Count > 5: " + count ); // 4
int [] filtered = Arrays . stream ( numbers )
. filter ( n -> n % 2 == 0 )
. sorted ()
. toArray ();
System . out . println ( "Even sorted: " + Arrays . toString ( filtered ));
// [2, 4, 6, 8]
// Generate array with streams
int [] squares = IntStream . rangeClosed ( 1 , 10 )
. map ( n -> n * n )
. toArray ();
System . out . println ( "Squares: " + Arrays . toString ( squares ));
// Parallel sort (large arrays benefit from this)
int [] large = IntStream . range ( 0 , 1_000_000 )
. map ( i -> ( int )( Math . random () * 1_000_000 ))
. toArray ();
Arrays . parallelSort ( large );
System . out . println ( "Parallel sorted. First: " + large [ 0 ] + ", Last: " + large [ large . length - 1 ] );
// mismatch (Java 9+)
int [] arr1 = { 1 , 2 , 3 , 4 , 5 };
int [] arr2 = { 1 , 2 , 99 , 4 , 5 };
int mismatchIdx = Arrays . mismatch ( arr1 , arr2 );
System . out . println ( "First mismatch at index: " + mismatchIdx ); // 2
}
}
// Example 5: Practical Array Algorithms
// File: ArrayAlgorithms.java
import java.util.Arrays ;
public class ArrayAlgorithms {
// Reverse an array in-place
static void reverse ( int [] arr ) {
int left = 0 , right = arr . length - 1 ;
while ( left < right ) {
int tmp = arr [ left ] ;
arr [ left ++] = arr [ right ] ;
arr [ right --] = tmp ;
}
}
// Rotate array left by k positions
static int [] rotateLeft ( int [] arr , int k ) {
int n = arr . length ;
if ( n == 0 ) return arr ;
k = k % n ;
int [] result = new int [ n ] ;
System . arraycopy ( arr , k , result , 0 , n - k );
System . arraycopy ( arr , 0 , result , n - k , k );
return result ;
}
// Two-sum: find indices with target sum
static int [] twoSum ( int [] nums , int target ) {
for ( int i = 0 ; i < nums . length ; i ++ ) {
for ( int j = i + 1 ; j < nums . length ; j ++ ) {
if ( nums [ i ] + nums [ j ] == target ) {
return new int [] { i , j };
}
}
}
return new int [] { - 1 , - 1 };
}
public static void main ( String [] args ) {
int [] arr = { 1 , 2 , 3 , 4 , 5 };
reverse ( arr );
System . out . println ( Arrays . toString ( arr )); // [5, 4, 3, 2, 1]
int [] rotated = rotateLeft ( new int [] { 1 , 2 , 3 , 4 , 5 }, 2 );
System . out . println ( Arrays . toString ( rotated )); // [3, 4, 5, 1, 2]
int [] indices = twoSum ( new int [] { 2 , 7 , 11 , 15 }, 9 );
System . out . println ( Arrays . toString ( indices )); // [0, 1]
// 2D array: find maximum element
int [][] grid = {{ 3 , 1 , 4 }, { 1 , 5 , 9 }, { 2 , 6 , 5 }};
int max = Arrays . stream ( grid )
. flatMapToInt ( Arrays :: stream )
. max ()
. orElse ( Integer . MIN_VALUE );
System . out . println ( "Grid max: " + max ); // 9
}
}
Section Topic URL JLS §10 Arrays https://docs.oracle.com/javase/specs/jls/se21/html/jls-10.html JLS §4.10.3 Subtyping among Array Types https://docs.oracle.com/javase/specs/jls/se21/html/jls-4.html#jls-4.10.3 JLS §15.10 Array Creation and Access https://docs.oracle.com/javase/specs/jls/se21/html/jls-15.html#jls-15.10 JLS §14.14.2 Enhanced for Statement https://docs.oracle.com/javase/specs/jls/se21/html/jls-14.html#jls-14.14.2 JVMS §6 Instruction Set (array ops) https://docs.oracle.com/javase/specs/jvms/se21/html/jvms-6.html JEP 431 Sequenced Collections https://openjdk.org/jeps/431
In this topic