Java中的对象类型和引用数组

Fix*_*xee 15 java arrays object

public class RefMix {
  public static void main(String[] args) {
    Object[] a = {null, "foo"};
    Object[] b = {"bar", b};
    a[0] = b;

    System.out.println(a[0][0]);
  }
}
Run Code Online (Sandbox Code Playgroud)

我的理解是数组是Java中的对象,因此是Object类型的子类.我的进一步理解是,2-dim数组被实现为对数组的引用数组.因此我不明白为什么我的a [0] [0] bar在上面的代码中没有产生.相反它不编译:

RefMix.java:7: array required, but java.lang.Object found
Run Code Online (Sandbox Code Playgroud)

Cod*_*ice 13

我的理解是数组是Java中的对象,因此是Object类型的子类.我的进一步理解是,2-dim数组被实现为对数组的引用数组.

这一切都是正确的,并解释了为什么你可以完成任务

a[0] = b;
Run Code Online (Sandbox Code Playgroud)

没有编译器的任何投诉.

因此我不明白为什么我的a [0] [0]在上面的代码中没有产生条形.

好的,我们来看看这个表达式中的类型:

  • aObject[]- 这是一个Objects 数组
  • a[0] 是一个 Object
  • a[0][0]- 现在你正在尝试使用数组下标Object.编译器不知道它Object实际上是一个数组,所以它抱怨.


Ant*_*ony 10

对象实例的运行时类型与静态推断类型不同.编译器将尝试估计程序中每个变量的类型,以便尽早捕获某些类型的错误.在这种情况下,a[0]将始终是一个数组,但编译器不知道这一点.由于您从对象数组中获取对象,因此所有编译器都知道这a[0]是一个对象.因此它会引发错误.

如果你知道某些东西总是某种类型,但是编译器无法解决它,你可以通过插入一个显式的强制转换来解决这个问题.

System.out.println(((Object[])a[0])[0]);
Run Code Online (Sandbox Code Playgroud)

  • @Fixee,Java中的数组相当丑陋,但您通常可以通过减少存储异构数据的次数来避免对转换的需求.您通常不需要将字符串和对象[]存储在同一个数组中. (3认同)
  • @Antimony我实际上找不到一个用例*你需要*这样的东西......;) (2认同)

bri*_*ium 7

你是对的,数组总是Objects在Java中,但Objects并不总是数组,因此你得到一个编译错误,因为它aObject[]一维的.你无法访问

a[0][0];
Run Code Online (Sandbox Code Playgroud)

因为a它不是一个二维数组(至少它没有被声明为这样).但是在这种情况下,你确定,这a[0]是一个数组Objects.因此,您可以这样做:

Object[] c = (Object[]) a[0];
System.out.println(c[0]);
// or directly:
System.out.println(((Object[])a[0])[0]);
Run Code Online (Sandbox Code Playgroud)

会将返回类型a[0](即Object)转换为a Object[],然后您可以访问数组的"第二层".