[英]What is the equivalent of Java's final in C#?
Java 在 C# 中的final
相当于什么?
final
关键字在 Java 中有几种用法。 它对应于两个sealed
和readonly
在C#的关键字,这取决于上下文中使用它。
防止子类化(从定义的类继承):
爪哇
public final class MyFinalClass {...}
C#
public sealed class MyFinalClass {...}
防止覆盖virtual
方法。
爪哇
public class MyClass
{
public final void myFinalMethod() {...}
}
C#
public class MyClass : MyBaseClass
{
public sealed override void MyFinalMethod() {...}
}
正如 Joachim Sauer 指出的那样,这两种语言之间的显着区别是 Java 默认将所有非静态方法标记为virtual
,而 C# 将它们标记为sealed
。 因此,如果您想停止进一步覆盖已在基类中显式标记为virtual
的方法,则只需在 C# 中使用sealed
关键字。
只允许一个变量被赋值一次:
爪哇
public final double pi = 3.14; // essentially a constant
C#
public readonly double pi = 3.14; // essentially a constant
作为旁注, readonly
关键字的效果与const
关键字的效果不同,因为readonly
表达式是在运行时而不是编译时计算的,因此允许任意表达式。
这取决于上下文。
final
类或方法, C# 等效项是sealed
。final
字段, C# 等效项是readonly
。final
局部变量或方法参数,没有直接的 C# 等效项。这里的每个人都缺少 Java 对 final 成员变量的明确赋值的保证。
对于具有最终成员变量 V 的类 C,通过 C 的每个构造函数的每条可能的执行路径都必须只分配 V 一次 - 未能分配 V 或分配 V 两次或更多次将导致错误。
C# 的 readonly 关键字没有这样的保证 - 编译器非常乐意保留 readonly 成员未分配或允许您在构造函数中多次分配它们。
所以,final 和 readonly(至少在成员变量方面)绝对不是等价的——final要严格得多。
如前所述,对于方法和类, sealed
相当于final
。
至于其余的,就复杂了。
对于static final
字段, static readonly
是最接近的。 它允许您在静态构造函数中初始化静态字段,这与 Java 中的静态初始化程序非常相似。 这适用于常量(原语和不可变对象)和对可变对象的常量引用。
const
修饰符与常量非常相似,但您不能在静态构造函数中设置它们。
在离开构造函数后不应重新分配的字段上,可以使用readonly
。 但它并不相等 - 即使在构造函数或初始值设定项中, final
需要一次赋值。
我所知道的final
局部变量没有 C# 等效项。 如果您想知道为什么有人需要它:您可以在 if-else、switch-case 等之前声明一个变量。 通过将其声明为 final,您强制它最多被分配一次。
Java 局部变量通常需要在读取之前至少分配一次。 除非分支在读取值之前跳出,否则最终变量只会被赋值一次。 所有这些都在编译时检查。 这需要行为良好的代码,错误余量较小。
总而言之,C# 没有直接等效的final
。 虽然 Java 缺少 C# 的一些不错的特性,但对于我来说,作为一个主要的 Java 程序员,看到 C# 无法提供等价物的地方让我耳目一新。
Java 类 final 和方法 final -> 密封。 Java 成员变量 final -> readonly 用于运行时常量,const 用于编译时常量。
局部变量 final 和方法参数 final 没有等价物
C# 常量使用 const 关键字声明为编译时常量或 readonly 关键字用于运行时常量。 常量的语义在 C# 和 Java 语言中是相同的。
密封
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.