Scala 最终类与非最终编译器优化
最终类对编译器有什么好处吗?当类是final和non-final时,它是否进行了任何优化?Scala 最终类与非最终编译器优化,scala,Scala,最终类对编译器有什么好处吗?当类是final和non-final时,它是否进行了任何优化? 我看到很多类在库代码中声明为final,所以我想知道。让我们先解决最重要的问题:是否使类成为final主要是程序员做出的建模决策final和non-final类具有不同的语义,因此纯粹出于性能原因不可能应用final 特别是,只有当类是final时,才能保证其属性和不变量。如果类不是final,子类可能会出现并重写方法,从而破坏(某些)属性和不变量 最明显的例子是,如果你想写一个不可变的类型:如果一个子类
我看到很多类在库代码中声明为final,所以我想知道。让我们先解决最重要的问题:是否使类
成为final
主要是程序员做出的建模决策final
和non-final
类具有不同的语义,因此纯粹出于性能原因不可能应用final
特别是,只有当类是final时,才能保证其属性和不变量。如果类不是final,子类可能会出现并重写方法,从而破坏(某些)属性和不变量
最明显的例子是,如果你想写一个不可变的类型:如果一个子类可以简单地用可变版本覆盖你的方法,那么就不能保证你的类型是不可变的,因此,如果你想你的类型是不可变的,它必须是final
由于Scala标准库、Scala平台以及更广泛的Scala生态系统和社区有许多不可变的类型,因此也将有许多final
类
因此,重复一次:使一个类成为最终的
是一个语义决策,它与优化无关。您通常无法选择是否将类设置为final
,它必须是final
以保留其不变量,或者它被设计为基类,在这种情况下,它不能是final
至于您关于编译器优化的问题:是的,编译器有一个好处。它实际上并不是关于
final
类,而是关于final
方法。对于某些优化,编译器必须证明此时无法重写方法。一般来说,这相当于解决停止问题,但是对于final
方法,这是非常正确的。因此,例如,您可以始终内联调用final
方法。让我们先解决最重要的问题:是否创建类final
主要是程序员做出的建模决策final
和non-final
类具有不同的语义,因此纯粹出于性能原因不可能应用final
特别是,只有当类是final时,才能保证其属性和不变量。如果类不是final,子类可能会出现并重写方法,从而破坏(某些)属性和不变量
最明显的例子是,如果你想写一个不可变的类型:如果一个子类可以简单地用可变版本覆盖你的方法,那么就不能保证你的类型是不可变的,因此,如果你想你的类型是不可变的,它必须是final
由于Scala标准库、Scala平台以及更广泛的Scala生态系统和社区有许多不可变的类型,因此也将有许多final
类
因此,重复一次:使一个类成为最终的
是一个语义决策,它与优化无关。您通常无法选择是否将类设置为final
,它必须是final
以保留其不变量,或者它被设计为基类,在这种情况下,它不能是final
至于您关于编译器优化的问题:是的,编译器有一个好处。它实际上并不是关于final
类,而是关于final
方法。对于某些优化,编译器必须证明此时无法重写方法。一般来说,这相当于解决停止问题,但是对于final
方法,这是非常正确的。因此,例如,您可以始终内联调用final
方法。根据:
final修饰符适用于类成员定义和类
定义。在中不能重写最终类成员定义
子类。模板不能继承最终类。决赛是
对象定义冗余。最终类或对象的成员
隐式也是final,因此final修饰符通常是
对他们来说也是多余的。但是,请注意,该常量值
定义(§4.1)确实需要明确的最终修饰语,即使
在最终类或对象中定义。最终版本可能不适用于
成员不完整,并且不能合并到一个修改器列表中
密封的
对于编译器来说,没有显著的性能改进或优势,只是语言约束的一部分 根据:
final修饰符适用于类成员定义和类
定义。在中不能重写最终类成员定义
子类。模板不能继承最终类。决赛是
对象定义冗余。最终类或对象的成员
隐式也是final,因此final修饰符通常是
对他们来说也是多余的。但是,请注意,该常量值
定义(§4.1)确实需要明确的最终修饰语,即使
在最终类或对象中定义。最终版本可能不适用于
成员不完整,并且不能合并到一个修改器列表中
密封的
对于编译器来说,没有显著的性能改进或优势,只是语言约束的一部分