为什么Java不允许扩展数组类型

7
作为一个实验,我尝试扩展一个int数组,如下所示:
public class IntArrayExtension extends int[]{
 // additional fields and methods.
}

我想在类本身中添加一些与排序、交换、子数组构建等相关的方法。但是在编译时,我遇到了以下错误:

IntArrayExtension.java:1: unexpected type
found   : int[]
required: class
public class IntArrayExtension extends int[]{
                                          ^
1 error

我很好奇:为什么Java不允许扩展数组?


这可能是一个更适合Programmers SE的问题。还可以查看我的问题这里 - Azar
1
可能是Java:将类扩展为数组的重复问题。 - Eran
因为它是一个原始类型而不是类。你可以从ArrayList继承,但你会得到List。 - Federico Piazza
1
@Eran 我不这么认为,因为那个问题问的是:Java是否允许这样做。而我的问题是:为什么Java不允许这样做呢? - Abhishek Oza
3个回答

13

扩展基本类型,如String或数组会导致安全漏洞。如果Java允许您扩展数组,那么接受数组作为参数的方法将变得不安全。这就是为什么字符串是final,而数组根本不能被扩展。

例如,您可以重写clone()方法,并返回一个错误大小的数组。这可能会破坏以数组作为其参数的系统代码的逻辑。

除此之外,在Java中,数组是特殊对象,它们没有类定义。

解决问题的两种方法:

  • 您可以将逻辑放入带有静态方法的辅助类中,类似于Collections等。
  • 您可以封装一个数组在您的IntArrayExtension类中,并提供包装器方法来访问数组及其附加功能。

我认为允许某人覆盖clone()方法的论点可能是无效的。如果超类的方法被声明为final,则它不能在派生类中被覆盖。 - Mitselplik
1
我明白他想要做这件事的原因。我也想这样做,将 Linq 风格的代码添加到 Java 中。不能像这样声明一个数组 Thing[] list = new Thing[100];,使用数组语法访问元素 Thing thisThing = list[50]; 并使用扩展方法 Thing[] subset = list.Where(new Comparator<Thing>,,,) 是不方便的。而且你也无法重载 [] 运算符来简化代码。 - Mitselplik

6

数组是对象,但数组类型不是类,因此无法被扩展。例如,参见JLS #10.8


0
实例 int[] 是 java.lang.Object 的实例,但 int[] 类型不是一个类(与 java.lang.Object 的任何其他实例不同),因此没有类可以扩展。这是 Java 中一些有趣的设计怪癖之一。
即使可能将 int[] 扩展为类似于类的对象,也可能不是实现所需功能的最佳方法:
- 它不是很通用,因为它只能对 int[] 数组进行排序/交换/复制等操作;而不能对其他类型的数组(如 double[])进行操作。这种自我限制是否必要? - 你所需要的数组功能在 java.util.Arrays 中都已经可用,它可以处理任何数组类型(int[]、double[]、MyAwesomeType<?>[] 等)。 - 仅仅为了添加更多功能而扩展类通常应该避免:现有的其他 int[] 数组需要成为你的新类的实例才能访问你的新功能,通常并不需要这样做(在这种情况下绝对不需要)。

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