gpt4 book ai didi

java - Java vs Scala类型层次结构

转载 作者:行者123 更新时间:2023-12-02 09:14:09 26 4
gpt4 key购买 nike

目前,我正在学习Scala,并且注意到Scala中的Type Hierarchy更加一致。 Any类型实际上是所有类型的超级类型,而Java Object只是所有引用类型的超级类型。

Java实例

Java方法导致引入了用于原语的包装器类,即自动装箱。这也导致具有不能是例如HashMaps中的键。所有这些都增加了语言的复杂性。

Integer i = new Integer(1); // Is it really needed? 1 is already an int.
HashMap<int, String> // Not valid, as int is not an Object sub type.





将所有类型都放在一个层次结构中似乎是一个好主意。这就引出了一个问题:为什么Java中没有所有类型的单一层次结构?基本类型和引用类型之间存在划分。它有一些优势吗?还是设计错误的决定?

最佳答案

这是一个相当广泛的问题。

存在许多不同的途径来解释这一点。我会尝试命名其中的一些。

Java关心较旧的代码。斯卡拉大都没有。

编程语言最终是由其社区定义的。除了您自己使用的语言外,其他语言都存在障碍,因为您不得不自己编写所有内容。这确实意味着,社区倾向于做事的方式确实在相当程度上反映了一种语言是否“好”。 java社区强烈希望合理的向后兼容性(合理性如下:如果确实有充分的理由不完全向后兼容,例如,因为您要破坏的功能很少使用,或者几乎总是以错误的方式使用,这没关系),Scala社区倾向于从一种时髦的新工作方式向另一种方式发展,并且任何没有进行非常积极开发的库要么根本无法工作,要么试图将其集成到更现代的Scala中图书馆是一个非常令人沮丧的练习。

Java不能那样工作。例如,在泛型中可以观察到这一点:泛型(List<T>中的T)不在Java 1.0中;它们是在Java 1.5中引入的,它们的引入方式是,所有现有代码都将继续正常运行,即使没有更新,所有库也可以在较新的代码中正常运行,并且适应现有代码以使用泛型不需要挑选新的库或进行了很多更新,而不仅仅是将泛型添加到源文件中的正确位置。

但这要付出代价:擦除。而且由于1.5版之前的List类可用于对象,因此泛型必须使用Object作为隐式绑定。 Java可以引入Any类型,但是它几乎没有用。您不能在很多地方使用它。

删除意味着,在Java中,泛型大部分是编译器想象力的体现:这就是为什么在给定列表实例的情况下,您不能问它的组件类型是什么?它根本不知道。您可以编写List<String> x = ...; String y = x.get(0);并能正常工作,但这是因为编译器为您注入了不可见的强制转换,并且它知道此强制转换是正常的,因为泛型为编译器提供了一个框架来判断此强制转换永远不会导致ClassCastException(除非明确尝试弄乱它,否则当您这样做时,编译器总是会发出警告。但是您不能将Object强制转换为int,这是有充分理由的。

Scala社区似乎更接受新的代码范例,而该范例仅与旧版本不交互。他们将重构所有代码,并更容易地保留一些较旧的库。

Java比scala更明确。

Scalac会推断出大量内容,这或多或少是该语言的设计方式(请参阅:隐式)。对于某些语言功能,您只能直接打电话:您正在为清晰性交易。在您不得不选择的地方,java往往会在清晰度方面出错。当我们谈论静默堆和包装器提升时,这特别显示出来:Java宁愿不这样做。是的,有自动装箱(无声包装),但无声地处理int,如果处理得当,它会比包装的变体快几个数量级,因为整个集合的包装变体只是为了写 对于Java来说是一座桥梁:大概很难意识到您正在吞噬所有性能方面的缺点。

这就是Java不能“随便”走的原因:嗯,无论如何,我们将引入Any类型,并在运行时通过静默包装内容将它们全部粘贴在一起。

原语是高性能的。

在Java中(而且scala在JVM上也可以运行在scala上),实际上实际上只有9种类型:int,long,double,short,float,boolean,char,byte和reference。例如,当您在内存中有一个int变量时,它实际上就是那个值,但是如果您有一个String变量,则该字符串位于某个地方的堆中,并且您到处传递的值就是指向它的指针。鉴于您不能直接打印指针或对其进行算术运算,因此在Java中,我们希望避免使用该术语,而应将其称为“引用”,但请不要犯错:这只是一个具有其他名称的指针。

指针本质上是浪费内存,性能较低。这种折衷的理由非常充分,但这就是事实。但是,尝试编写既可以处理直接值又可以处理引用的代码并不容易。通过使编写不可知的代码(这是 List<int>类型试图完成的代码)相对困难而使这种复杂性浮现在您的面前,这是确保程序员不会对此感到困惑的一种方法。

未来

总结以上三点,希望现在很清楚 Any类型会导致很多缺点,或者大多数情况下将是无用的(您无法在任何地方使用它)。

但是,即将出现好消息。 Google表示“ Project Valhalla”和“ java值类型”。这是一项艰巨的尝试,将尝试允许Any类型带给您的很多东​​西,包括有效的泛型基元。以与现有Java代码集成的方式,就像Java的闭包方法意味着Java不需要结成Scala臭名昭著的 Any和朋友一样。正确地做起来往往会比较困难,因此花了相当长的时间,并且项目valhalla尚未完成。但是,如果是的话,您将能够编写 Function8<A,B,C,D,E,F,G,H,R>并使用 List<int> list = new ArrayList<int>类型,并且它们将尽可能地具有高性能,并尽可能地与现有的Java代码集成。 Valhalla项目不是JDK14的一部分,也可能不会达到15。

关于java - Java vs Scala类型层次结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59139237/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com