Scala数组类型推断疑问:new Array(3)为何返回Nothing而非类似Java的Object
new Array(3)返回Nothing类型的问题解答 先把你的代码场景理清楚:
var arr = new Array(3) ' 你提到这里返回类型为Nothing arr(0) = "Hi" ' 执行这行时抛出错误
作为有丰富Java经验的开发者,你疑惑为什么VB不像Java那样返回一个类似Object的通用超类型,让你能随意赋值任意类型,甚至怀疑是不是自己误解了类型推断逻辑,或者这是VB有意的设计。我来一步步给你解释:
首先,你对new Array(3)的理解有偏差
在VB(尤其是VB.NET)里,System.Array是所有数组类型的抽象基类——它本身不能被直接实例化!你写的new Array(3)其实并没有创建出一个可用的数组对象,反而得到的是一个Nothing(相当于Java里的null)。这就是为什么你给arr(0)赋值时会报错:你在试图给一个空引用的元素赋值,自然会抛出空引用异常。
而Java里的new Object[3]是完全不同的逻辑:Object是具体类,Object[]是一个具体的数组类型,编译器会帮你创建一个长度为3的数组实例,每个元素默认是null,所以你可以正常给元素赋值任意类型的对象。
要在VB里实现类似Java Object数组的效果,得这么写
如果你想创建一个能存储任意类型的数组,需要明确指定数组的元素类型为Object,比如:
' 方式1:显式声明类型 Dim arr As Object() = New Object(2) {} ' 长度为3,索引范围0-2 arr(0) = "Hi" ' 完全没问题 ' 方式2:用类型推断 Dim arr = New Object(2) {} arr(0) = 123 ' 存数字也可以 arr(1) = True ' 存布尔值也ok
关于类型推断的逻辑
VB的类型推断是根据右侧表达式的实际有效结果来确定变量类型的。当你写new Array(3)时,编译器知道Array是抽象类,无法实例化,所以这个表达式的结果是Nothing,变量arr的类型会被推断为Array,但实际引用的是Nothing——这就导致后续赋值操作必然失败。
这确实是有意的设计
System.Array被设计成抽象基类,就是为了让所有具体的数组类型(比如String()、Object())去继承它,而不是让开发者直接实例化它。VB这么设计的核心是类型安全:如果你的数组是用来存字符串的,就应该声明为String(),而不是用通用的Object(),这样编译器就能在编译阶段帮你检查类型错误,避免运行时的类型转换异常。
其实本质上和Java的设计思路是一致的——Java里你也不会直接去实例化java.lang.reflect.Array(类似VB的System.Array),而是直接创建具体的数组类型。
内容的提问来源于stack exchange,提问作者Gibbs

