Java的C#最终版本等效于什么?


Answers:


860

final关键字在Java中的几个用途。它取决于C#中的sealedreadonly关键字,具体取决于使用它的上下文。

班级

为了防止子类化(继承自定义的类):

爪哇

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。因此,仅sealed当您想停止进一步重写已virtual在基类中显式标记的方法时,才需要在C#中使用关键字。

变数

仅允许一次分配变量:

爪哇

public final double pi = 3.14; // essentially a constant

C#

public readonly double pi = 3.14; // essentially a constant

作为边注,所述的效果readonly关键词不同于所述的const,所述关键字readonly表达在评价运行时,而不是编译时,因此允许任意表达式。


15
我要补充一点,默认情况下,Java中的所有非静态方法都是虚拟的。因此,在C#中,您可以只在初始定义中忽略虚拟,而您需要使用“ final”以避免子类在Java中覆盖它
Joachim Sauer 2009年

166
好的答案-尽管在Java中还有“ final”的另一种用法-在局部变量或方法参数上可以防止重新分配它。没有c#的直接等效项。
serg10,2009年

17
readonly可以在构造函数中修改成员变量:pastebin.com/AzqzYGiA
递归

8
另请注意:如果你声明一个成员变量为final在Java中,编译器会抱怨,如果不是每一个构造受让人在每一个代码路径的值,而C#只发出在场景中有只读成员变量的警告
梅内

1
@NickolayKondratyev:是的,我的示例是隐式的,因为您需要从另一个类进行子类化。您实际上不需要界面;那是多余的,但否则看起来是正确的。
Noldorin

180

这取决于上下文。


1
实际上,在声明最终变量时并不需要分配最终变量。“最终”表示变量必须在引用之前由某个代码路径分配,并且没有代码路径允许多次分配该变量。这适用于实例变量,实际上意味着构造函数必须显式分配变量。
周杰伦2012年

31
+ For a final local variable or method parameter, there's no direct C# equivalent有很大的区别。
Daniel B. Chapman

1
如果要实例化,可以使用局部变量的const。这不是等效的,因为final可以让您分别声明和初始化(因此具有不同的值),但是以防万一您不知道...
Griknok

3
const只能用于值类型。据我所知,没有办法为本地引用类型设置有效常数。
jocull

2
@jocull字符串是唯一的例外。
RaimundKrämer18年

46

这里每个人都缺少的是Java对最终成员变量的确定赋值的保证。

对于具有最终成员变量V的类C,通过C的每个构造函数的每个可能的执行路径必须精确地分配一次V-未能分配V或两次或多次分配V将导致错误。

C#的readonly关键字没有这样的保证-编译器非常乐意保留未分配的只读成员,或者允许您在构造函数中多次分配它们。

因此,final和readonly(至少在成员变量方面)绝对不是等效的-final更为严格。


7

如前所述,sealed等效于finalfor方法和类。

至于其他,则很复杂。

  • 对于static final字段,static readonly是最接近的事情。它允许您在静态构造函数中初始化静态字段,这与Java中的静态初始化程序非常相似。这既适用于常量(原始对象和不可变对象),也适用于对可变对象的常量引用。

    const修正是常数非常相似,但你不能将它们放置在静态构造函数。

  • 在离开构造函数后不应重新分配的字段上,readonly可以使用。但是,它并不相等- final甚至在构造函数或初始化程序中也只需要一个赋值。
  • final我所知道的局部变量没有C#等效项。如果您想知道为什么有人会需要它:您可以在if-else,switch-case左右之前声明一个变量。通过最终声明,您可以强制对其最多分配一次。

    通常,Java局部变量在读取前至少需要分配一次。除非分支在读取值之前跳出,否则最终变量将只分配一次。所有这些都在编译时检查。这需要行为良好的代码,且错误容限较小。

总结起来,C#没有与的直接等效final。尽管Java缺少C#的某些出色功能,但对于大多数Java程序员来说,看到C#无法提供等效的东西对我来说是令人耳目一新的。


6

Java类final和方法final->密封。Java成员变量final->只读表示运行时常量,const表示编译时间常量。

没有等效的局部变量fi​​nal和方法参数final



0

密封


8
这只是答案的一部分,因为它取决于上下文,并添加说明和/或示例将使那些需要帮助的人更容易理解
Rune FS
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.