在Java中,数组是一个对象吗?

107

在Java中我们可以使用以下方式声明数组:

String[] array = new String[10]; 
int size = array.length; 

这是否意味着数组本身是一个对象?我这样问是因为在C++中,数组只是一个指针,并没有任何方法。


5
不,C++中的数组就是数组,而不是不是数组。 - Kerrek SB
51
如果(array是Object的一个实例),则输出“Yes!” - skaffman
6
在C++中,数组和指针都是对象。 - R. Martinho Fernandes
2
@R.MartinhoFernandes 所有的 C++ 数组确实都是 C++ 对象,但是有些 C++ 指针不是 C++ 对象,即所有由求值 rvalue 得到的指针。例如 &xp+inew int(42) - fredoverflow
1
@skaffman 这条消息并不是必需的,因为否则它将无法编译。 - shmosel
显示剩余3条评论
14个回答

209

可以。

Java语言规范第4.3.1节开始如下描述:

对象是一个类实例或者一个数组。


6
直到现在,我一直认为对象和类实例是同义词,并且数组是一种特殊的语言功能或其他什么东西。 - Ruben9922
这里提供了详细的解释:https://www.geeksforgeeks.org/array-primitive-type-object-java/ - garnet

64

是的,Java语言规范写道:

在Java编程语言中,数组是对象(§4.3.1),动态创建并且可以分配给 Object 类型的变量(§4.3.2)。所有 Object 类的方法都可以在数组上调用。


1
如果数组是一个对象,那么这是否意味着它是一个类的实例?如果是这样,我可以扩展那个类吗? - One Two Three
12
不,它不行。Java规范写道:“对象是类实例或数组。类实例通过类实例创建表达式(§15.9)显式创建。数组通过数组创建表达式(§15.10)显式创建。” 而且,不可以扩展一个数组,因为extends子句必须包含一个ClassType。 - meriton

41

好的,让我们问问Java!

public class HelloWorld
{
  public static void main(String[] args)
  {
    System.out.println(args instanceof Object);
    int[] someIntegers = new int[] {42};
    System.out.println(someIntegers instanceof Object);
  }
}

输出:

true
true

1
您还可以声明int[] someIntegers = {42};,得到相同的结果。 - Holger

9

是的,它是Java中的一个对象。

还要注意的是,当你执行array.length时,你并没有调用任何方法,只是访问数组的length字段。在Arrays类中有很多静态方法。


5

需要注意的是,在Java中,数组具有独立的字节码,不与对象共享。它们虽然是对象,但在低级别上处理略有不同。


5
  1. 数组不是类树中列出的任何类的实例,但每个数组都是一个对象,并直接继承自java.util.Object
(new int[1]) instanceof Object   // -> evaluates to true
  1. java.util.Arrays类是一个辅助类,数组不是该类的实例。
(new int[1]) instanceof java.util.Arrays    // -> compile error
  1. java.lang.reflect.Array类是一个辅助类,数组不是该类的实例。
(new int[1]) instanceof java.lang.reflect.Array    // -> compile error
  1. 数组继承了java.lang.Object的所有成员。

  2. 数组覆盖了从Object继承而来的clone()方法。

  3. 数组实现了包含数组组件数量的字段length。长度可以是正数或零。它是publicfinal的。

  4. 数组实现了接口Cloneablejava.io.Serializable

8a. 数组由Class<T>支持。您可以从数组实例中检索Class<T>实例。

(new int[2]).getClass()

或者来自一个数组类型
int[].class

8b. 您的代码中每个不同的数组类型都会创建一个唯一的反射类实例(即 java.lang.Class<T> 的实例)。例如:

int[].class.getCanonicalName()    //  -> "int[]"
String[].class.getCanonicalName() //  -> "java.lang.String[]" /

重申一遍:数组是对象,但不属于类树中的任何一个类的实例。

参考资料

来自Java规范 第4.3.1节 对象

  • 对象是类实例或数组。

  • 类实例由类实例创建表达式显式创建。

  • 数组由数组创建表达式显式创建。

来自 java.util.Arrays

  • 该类包含各种用于操作数组(例如排序和搜索)的方法

来自 java.lang.reflect.Array

  • Array类提供了静态方法以动态创建和访问Java数组。

来自第10.1节 对象

  • 数组类型的直接超类是Object

  • 每个数组类型都实现了接口Cloneablejava.io.Serializable

来自第10.7节 数组成员

数组类型的成员包括以下所有内容:

  • 公共的 final 字段 length,它包含数组的组件数。长度可以是正数或零。

  • 公共的方法 clone,它重写了类 Object 中同名方法,并且不会抛出已检查异常。数组类型 T[]clone 方法的返回类型是 T[]

  • 多维数组的克隆是浅层的,也就是说它只创建一个新数组。子数组是共享的。

  • 所有从类 Object 继承的成员;唯一没有继承的 Object 方法是它的 clone 方法。


3

2

我认为答案是肯定的,尽管严格来说,在C ++中数组也是一个对象。根据当前标准(FDIS)的§1.8 [intro.object]:

对象是存储区域。


1

Java 中的每个数组都是一个对象,例如 int[] a=new int [2]; 所以 new 用于创建对象,由于它是一个对象,我们可以使用 a.getClass().getName() 检查类名。


1
在Java中,数组是对象,并且是动态创建的。数组可以分配给类型为Object的变量,并且可以在数组上调用所有类型为Object的方法。一个数组可以包含多个变量,或者也可以不包含任何变量,在这种情况下,它被称为空数组。

我不理解这部分内容:“可以在数组上调用类型为Object的所有方法”。你能举个例子吗? - codeogeek
1
@codeogeek 一个方法是一段代码块,只有在被调用时才会运行。您可以将数据(称为参数)传递到方法中,它们用于执行某些操作。例如,toString() 方法将数组转换为字符串表示形式。System.out.println(Arrays.toString(arr))``` 输出:[111 bbbb london, 131 aaaa nyc, 121 cccc jaipur] - Ayan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接