【问题标题】:Zero length multidimensional array零长度多维数组
【发布时间】:2016-01-14 12:58:45
【问题描述】:

我知道类似的问题已经被问过好几次了,他们得到了很好的回答,但是......它们大约是一维的零长度数组,例如:

int[] array = new int[0];

似乎在不应/不能使用 null 的情况下使用此类数组是有目的的。但是为什么 Java 允许创建这样的东西:

int[][][] multiDims = new int[5][0][9];

当然,就像在简单的 1D 情况下,如果我们尝试迭代或其他东西,我们不会从这样的数组中得到任何东西,我只是因为它看起来对我来说非常讨厌。 :-) 给这种无意义的生物分配了多少内存?

【问题讨论】:

  • 你的问题是为什么允许还是分配了多少内存?
  • 开发人员一直在编写无意义的代码,并且不可能检测到开发人员可以提出的每一个无意义的组​​合。
  • 看来你也可以成功编译new int[-1] ideone (但是它在运行时显然会失败)。这看起来像是 Google's error-prone 之类的工具可能会着手捕获的错误(尽管它目前看起来没有,可能是因为它太愚蠢)。
  • 如果您不允许这样做,它将强制程序员对在当前规范下自然工作的情况进行特殊情况处理。

标签: java arrays


【解决方案1】:

至于为什么 Java 允许这样做 - 从语言的角度来看(而不是您试图用它表达的概念),为什么它应该明确禁止这样做?如果您允许任何类型的零长度数组,为什么要特别禁止int[9] 的零长度数组?禁止它需要更多的编译器检查来强制执行一个基本上无用的规则,因为即使没有该规则,行为也得到了很好的定义。

归根结底,编译器检查不是为了确保您的程序有意义。他们来这里只是为了检查它是否明确。


编辑添加:

正如 cmets 中所指出的,这种检查甚至是不可能的,因为数组长度不是类型信息的一部分,可以在运行时给出。因此,除了源代码中直接存在int[0] 的“特殊情况”之外,编译器甚至无法知道它是否是零长度数组。

【讨论】:

  • 这是一个零长度数组int[]。大小不是 Java 中类型的一部分。
  • 还要注意,这是特例中的特例。在 Java 中,维度不需要是常量,因此,总有一种方法可以将这些数字准确地传递给数组创建表达式,而编译器却无法预测。对于动态值,这种组合在上下文中可能是有意义的。
  • @Holger 好点,我编辑了答案。这很好地说明了为什么检查不仅不切实际而且通常是不可能的。
【解决方案2】:

这将创建 6 个对象 - 5 个空数组和一个包含这些数组的数组。

为什么允许?出于与一维数组相同的原因。如果你创建一个这样的数组:

int[][][] multiDims = new int[p][q][r];

其中每个p、q 和r 有时可能是0,处理这些特殊情况将非常困难。相反,您会得到一个可以在循环中使用的合法对象(一个非常短的循环 - 一个立即结束但没有错误的循环)。

【讨论】:

  • 您的观点避免了对特殊情况的需求是一个很好的观点。许多语言标准的维护者似乎采取这样的态度,即如果在特定情况下执行某些构造没有用处,那么即使它允许有用的概括,也没有理由支持它,所以我喜欢看到允许的地方的例子这样的概括很有用。令人讨厌地不允许这种用法的语言的一个例子是 C99;它允许使用在运行时计算的大小声明数组,但声明一个大小为零的数组会调用未定义行为,即使代码...
  • ...从不尝试实际访问它(例如,对数组的所有访问都在 for 循环中,如果大小为零,则其主体永远不会执行),C 中的未定义行为是比 Java 中存在的任何东西都糟糕,因为它允许编译器将所有时间和因果关系的概念抛到窗外。
【解决方案3】:

[5] 实际上做了一些有用的事情:最外面的数组将有五个长度为 0 的元素数组。

但您对[9] 的看法是正确的。它什么都不做:因为所有五个中间数组都是空的,所以不会创建长度为 9 的数组。任何整数都可以放在那里达到完全相同的效果。

语言可以被设计成如果有一级嵌套数组的维度设置为文字0,那么所有后续级别也必须设置为文字0。但这会在规范和实现中创建另一个特殊情况,并且收益将非常小。

【讨论】:

  • [9] 实际上可能有一个目的。也许不是功能性的,而是语义性的:这意味着数组的第三维应该的长度为 9,如果您计划添加元素以使第二维不再为空,这可能会很有用.
  • @Darkhogg 实例化后无法调整 Java 数组的大小
  • @Max 这样吗?您可以将空数组交换为非空数组。
  • @Darkhogg 如果您将其中一个顶级数组替换为另一个数组,那么被替换数组的原始维度是多少并不重要。示例见ideone.com/cHvI84
  • @Darkhogg 虽然我刚刚意识到我可能误解了您的原始评论。我同意在某些情况下,为了语义清晰,这样做更有意义,无论其功能方面如何
猜你喜欢
  • 1970-01-01
  • 2023-02-25
  • 2012-09-06
  • 2014-11-29
  • 1970-01-01
  • 2013-05-17
  • 2013-08-21
  • 2011-08-22
  • 2013-10-10
相关资源
最近更新 更多