The introduction

concept

An array is a linear data structure. It uses a set of continuous memory space to store a set of data of the same data type, represents a set of data of the same type, has a fixed length, and occupies a continuous space in memory.

Arrays are a data type common to almost all languages, and they’re something we’ll often encounter during development, so it’s important to understand their properties

Arrays are defined and used through square brackets[].

In Java, an array is a reference type.

In Java, arrays are used to store fixed-size elements of the same type.

Different from C/C++ arrays

Storage structure differences:

C arrays: Array space is given once, preferentially accessing low addresses, and putting elements from bottom up.

They are contiguous in memory, and all arrays are contiguous and can be treated as one-dimensional arrays.

In addition, C arrays can be dynamically allocated, i.e. dynamically expanded, whereas Java arrays cannot. Of course, Java also provides ArrayList dynamic arrays

In the figure below, a two-dimensional array can be regarded as a one-dimensional array, except that the elements in it are one-dimensional arrays. So the array in C is linear

In Java, arrays refer to entity variables in a tree structure. Each leaf node has nothing to do with each other but a reference relationship. Each reference variable refers to only one entity.

Java arrays do boundary checking, so when you go out of bounds, you throw a RuntimeException, whereas in C or C++ they don’t do boundary checking

In the diagram, the example above looks like this. In heap memory, the elements of one-dimensional arrays are contiguous, but the arrays are not contiguous.

Is an array an object?

C is a process-oriented language and will not be discussed here

Arrays in C++ are not objects, just collections of data, whereas arrays in Java are objects, as we’ll see and verify later

Distinguished from container

In Java, a container is something that holds multiple objects. Strictly speaking, it saves references to objects. Because the actual data for the object is in a different place. Placed in the container is just an identifier pointing to that memory area

Is there no need for arrays in Java, now that we have powerful containers? The answer is no

Of course, in most cases, you should choose containers to store your data.

The differences between arrays and containers are efficiency, type recognition, and the ability to hold primitive types

1. In Java, arrays are the most efficient way to store and randomly access sequences of object references. Arrays are more efficient than containers (like ArrayList)

2. In terms of type recognition, The Java containers List, Set, and Map treat objects as if they had no type of their own. The container treats its elements as if they were of the root Object type, so that we can create a container that holds all types of objects in it. But when we take out data, we need to do our own type conversion, this problem in Java after the introduction of generic type checking, and container classes can be used to solve the problem of type conversion

3. Arrays can hold value types, containers can’t (must use wrapper classes)

An array of features

Random access

Non-random access: when accessing the NTH data, the first (n-1) data must be accessed first (linked list)

Random access: access to the NTH data, without accessing the first (n-1) data, can directly operate on the NTH data (array).

How can arrays be randomly accessed?

In fact, the array data is stored sequentially in the contiguous space of memory. As we can see from the above figure, even though the Java 2d array is in a tree structure, the elements of each one-dimensional array are contiguous. Arr [0], ARR [1] and other array objects point to the one-dimensional array. So the memory address (location in memory) of each piece of data can be calculated using the array subscript, which allows us to directly access the target data, i.e. random access

Java arrays and memory

This is a little bit confusing, but can you draw a diagram to see how Java arrays are stored in memory?

Array objects (analogous to Pointers) are stored on the stack, and array elements are stored in the heap

One-dimensional arrays:

Two-dimensional arrays:

One-dimensional arrays store values directly in contiguous memory space on the heap, and two-dimensional arrays store reference addresses of one-dimensional arrays at contiguous addresses. One-dimensional arrays and one-dimensional arrays do not necessarily sit next to each other, but their internal values are at contiguous addresses. Higher dimensional arrays continue the analogy, with only the last one dimensional array holding values at consecutive addresses, and all other latitudes holding the next dimensional reference address at consecutive addresses. Instances of the same dimension are not necessarily next to each other.

To reassure

Why do array subscripts start at 0?

In the memory model of array storage, the most accurate definition of “subscript” should be “offset”. If a[0] represents the beginning of the array, a[0] represents the beginning of the array, and a[k] represents the beginning of the array. If a[0] represents the beginning of the array, a[k] represents the beginning of the array.

a[k]_address = base_address + k * type_size
Copy the code

However, if the array counts from 1, then we calculate the memory address of the array element a[k] as:

a[k]_address = base_address + (k-1)*type_size
Copy the code

Comparing the two formulas, it can be found that starting from 0, each random access to the array element is one less subtraction operation, for the CPU, that is, one less subtraction instruction, improve the efficiency of access

The nature of arrays

Are arrays objects in Java?

Java and C++ are both object-oriented languages. With these languages, you can either use standard class libraries directly, or you can use object-oriented features like composition and inheritance to build your own classes and create objects from the classes you build. So should we consider the question: are arrays objects in an object-oriented language?

To determine whether an array is an object, we must first define what an object is, namely the definition of an object. At a higher level, an object is an instance of a class that represents a specific individual of a class. Objects have various properties and have some specific behavior. At a lower level, from a computer’s point of view, an object is a block of memory that encapsulates some data, that is, the properties defined in a class, so an object is used to encapsulate data. The following is an in-memory representation of a Person object:

Note:

1. The red rectangle represents a reference (address) or a basic type of data. The green rectangle represents an object.

2. Name in an object represents only a reference, that is, an address value, to a real string object. Here a strict distinction is made between references and objects.

So in Java, do arrays meet these criteria? At a high level, an array is not a concrete individual of something, but rather a collection of individuals. So it shouldn’t be an object. From a computer’s point of view, an array is also a block of memory that encapsulates some data, so it can also be called an object. Here is an in-memory representation of an array:

In this case, an array can be an object or not. It is up to the Java designers to decide whether to treat arrays as objects. Verify that an array is an object:

int[] arr = new int[4];
int len = arr.length;  // The array holds a field that represents the length of the array

// The following methods show that arrays can call methods. Java arrays are objects. These methods are methods in Object, so you can be sure that the topmost parent of the array is also Object
arr.clone();
arr.toString();
Copy the code

From the code above, on the array ARR, you can access its properties and call some methods. This basically assumes that arrays in Java are objects that have some of the basic characteristics of other Objects in Java: they encapsulate some data, they can access properties, and they can call methods. So the answer is yes, arrays are objects.

As the authoritative Java Language Specification puts it:

In the Java Programming language, Arrays are Dynamically created And may be assigned to variables of type Object (§4.3.2). All methods of class Object may be invoked on an array.

Here I will not give you the translation, do not understand the Youdao translation

Add: The Java Language Specification for Array:

Every array has an associated Class object, shared with all other arrays with the same component type. [ This] acts as if: the direct superclass of an array type is Object [ and] every array type implements the interfaces Cloneable and java. io. Serializable.

Array objects are not instantiated from a class, but are created directly by the JVM. There’s actually no Array class either (there is, but it’s just a reflection class in the java.lang.Reflect package). But each array corresponds to a Class object. With **RTTI (Run-time Type Information) ** you can directly check the runtime Type of an Array, its signature, its base class, and much more. In C++, an array encapsulates data, but the array name is just a pointer to the first element in the array. There are no attributes and no methods to call. The following code looks like this:

int main(a){
	int a[] = {1.2.3.4};
	int* pa = a;
	// Properties cannot be accessed and methods cannot be called.
	return 0;
}
Copy the code

So an array in C++ is not an object, but a collection of data, and cannot be used as an object.

The type of an array in Java

Java is a strongly typed language. Since it is an object, it must be of a type, such as creating an object based on the Person class, which is of type Person. So what’s the type of the array? Look at the following code:

int[] arrI = {1.2.3.4};
System.out.println(arrI.getClass().getName());

String[] arrS = new String[2];
System.out.println(arrS.getClass().getName());

String[][] arrsS = new String[2] [3];
System.out.println(arrsS.getClass().getName());

OutPut:
[I
[Ljava.lang.String;
[[Ljava.lang.String;
Copy the code

ArrI is of type [I, arrS is of type [ljava.lang.String; arrsS is of type [[ljava.lang.String;

So, the ** array is also typed. ** It’s just that this type is weird. You can say that arrI is of type int[], and rightly so. But we didn’t create the class ourselves, nor did we find it in the Java standard library. This means that neither our own code nor the JDK has the following definition:

public class int[] {
	
	// ...
}
Copy the code

This can only be explained by the fact that the array Object is not instantiated from a class, but is created directly by the JVM, and the parent of this directly created Object is Object, so you can call all the methods in Object, including the toString() you used.

We can think of array types as Java’s built-in types, along with the eight basic data types. These types are named like this:

Each dimension is represented by a [; the first two [represent a two-dimensional array.

At the Java language level, it makes sense that arrS is both an array and an object, so it should be of type String[]. In the JVM, however, it is of type java.lang.string. By the way, ordinary classes in the JVM are of type package name + class name, i.e., fully qualified name. The same type may be represented differently in the Java language and in virtual machines.

Inheritance of arrays in Java

As we’ve already verified, arrays are objects, which means you can manipulate arrays the same way you manipulate objects. And arrays have special types in virtual machines. Since it is an Object, it follows the rules of the Java language — Object is God, which means that the top-level parent of all classes is Object. The top parent of an array must also be Object, which means that an array Object can be cast directly up to Object, cast downward, or typed using the instanceof keyword. It’s all the same as normal objects. The following code looks like this:

Test1 () : array is an Object. The top parent of an array is Object, so it can be cast upward
int[] a = new int[8];
Object obj = a ; // The parent class of the array is also Object, and we can cast a up to Object

//2 Can you transition down?
int[] b = (int[])obj;  // You can make a downward transition

//3 Can use the instanceof keyword to determine?
if(obj instanceof int[]) {// You can use the instanceof keyword to determine the type
    System.out.println("The true type of obj is int[]");
}
Copy the code

References:

What is an array?

Java and C array differences

Array features in Java

Are arrays objects in Java? — Look at Sunny and Fat Jun’s answers