为什么在静态类型语言中声明类型很重要?

7

我试图理解编程语言静态类型的好处,通过这个问题,我想知道为什么我们需要在声明中包含类型?它除了使类型显式外,还有其他作用吗?如果是这样,我就看不到它的意义。我知道静态类型允许在编译时进行类型检查,但如果我们省略显式类型声明,Java 是否仍然可以在编译时推断类型呢?

例如,在 Java 中:

myClass test = new myClass();

这里是否需要类型声明?如果我没记错,这是静态绑定,即使在编译时没有显式声明类型,Java也应该知道test的类型是myClass。
回复可能的重复问题:这不是关于静态与动态类型的问题,而是关于静态类型语言中类型推断的问题,正如被接受的答案所解释的那样。

3
如果你有一个class B extends A,以及A a = new B(),编译器应该如何推断a的类型? - gefei
@femtoRgon 这个问题是关于静态类型语言中的类型推断,而不是动态类型语言。 - yshavit
抱歉,这不是关于动态类型语言的话题。 :) - yshavit
2个回答

11

有一些静态类型语言允许您省略类型声明,这被称为类型推断。不过它的缺点是设计更加困难(对于语言设计者),实现更加困难(对于编译器开发者),并且当出现问题时理解起来可能更加困难(对于程序员)。最后一个问题是如果您的很多(或所有)类型都是推断出来的,那么编译器不能告诉您更多信息,通常只能输出一条晦涩难懂的消息:“类型不一致”。

像您提到的这个简单情况中,是可以做到类型推断的。但是当情况变得更加复杂时,该系统很快就会变得非常复杂。

Java确实在非常有限的形式下进行了一些类型推断。例如,在此片段中:

List<String> emptyStrings = Collections.emptyList();

编译器推断出方法调用emptyList返回一个List<String>,而不仅仅是一个类型未指定的List<T>。该行的非推断版本(也是有效的Java代码)是:

List<String> emptyStrings = Collections.<String> emptyList();

1
这正是我想知道的,谢谢!那么现在我有另一个类似的问题:在像Java这样的语言中,声明的类型是否会分配不同数量的内存?例如 A a;B b;,如果 A 有100个实例变量而 B 没有,那么在声明时会有任何区别吗?或者这只是在实例化时才有区别?原始数据类型呢? - rb612
2
@rb612 它完全没有任何区别;内存纯粹由对象决定,而不是由对它的引用决定。引用只是一个固定大小,因此三个引用 String aList<String> bArrayList<HashMap<String, String>> c 将占用完全相同的空间(实际上,JVM 甚至不知道它们是除了“某个对象的引用”之外的任何东西)。原始类型根本没有多态性,但它们确实有不同的大小(一个字节只有一个字节,一个短整型有两个字节等等)。 - yshavit
太好了,谢谢!因此,在像Java这样的静态类型语言中显式声明类型仅用于避免类型推断,与内存分配无关。 - rb612

1

这是必要的。您可以使用继承,其中类型是必需的。

例如:

Building build1 = new House();
Building build2 = new SkyScraper();

在多态中也是一样的。
你可以将所有的建筑物收集到数组中。例如,如果有一个房子和一座摩天大楼,你就不能这样做。

我明白你的意思。但是如果你想让build1只是一个房子,比如 House build1 = new House();,那么你应该可以放弃第一个House,直接写成 build1 = new House();,对吧? - rb612
谢谢。我觉得我的问题没有表达清楚,与类型推断有更多关系,这正是@yshavit回答中所解释的。 - rb612

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