主要观点:
- 研究了面向对象语言中构造函数的工作方式,以 Ruby 和 Java 为例进行对比。
- 探讨了构造函数在不同语言中的特点及与其他实例方法的差异。
- 研究构造函数对覆盖检查的影响,以及不同语言对此的处理方式。
- 考察构造函数与类型推断的重叠问题及其他语言的处理方式。
关键信息:
- Ruby 中构造函数
initialize是实例方法,通过new调用,new方法在 Ruby VM 中定义,其实现类似Class#new方法,先分配内存再调用initialize,若未实现initialize则调用BasicObject#initialize。 - Java 中构造函数通过
new分配内存,通过invokespecial调用initialize,有特殊的<init>方法,默认构造函数由 Java 编译器处理,子类若未定义构造函数需调用super(...)。 - 像 Java 等语言不进行构造函数的覆盖检查,而 Ruby 和 Sorbet 不能采用此方式,其他语言如 Python 和 Flow 忽略该问题,Hack 有注解可进行检查,TypeScript 采用结构类型回避该问题。
- Sorbet 在处理构造函数与类型推断的重叠问题时,不会推断类的泛型类型参数用于方法,未来可能考虑类似其他语言的处理方式。
重要细节:
- Ruby 中通过
rg 'Class.*"new"'在 Ruby VM 源代码中查找Class#new的实现。 - Java 中的字节码指令如
new和invokespecial分别用于分配内存和初始化实例。 - 在 Ruby 中,
new方法是单例类方法,动态调度;在 Java 中,invokespecial是介于静态和动态调度之间的交叉类型。 - Sorbet 在处理构造函数相关问题时仍存在未解决的情况,如覆盖检查和类型推断等。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用。你还可以使用@来通知其他用户。