C#でのJavaのfinalに相当するものは何ですか?


560

finalC#でのJavaに相当するものは何ですか?


131
「このクラスをオーバーライドすると解雇されます!」というクラスのトップへのコメント (もちろん冗談です:)
Hemant

回答:


861

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が指摘するように、ここでの2つの言語の顕著な違いは、Javaはデフォルトですべての非静的メソッドをとしてvirtualマークするのに対し、C#はそれらをとしてマークすることsealedです。したがって、基本クラスでsealed明示的にマークさvirtualれているメソッドのオーバーライドをこれ以上停止しない場合は、C#でキーワードを使用するだけで済みます。

変数

変数を1回だけ割り当てることを許可するには:

ジャワ

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#では初期定義で仮想を単に省略できますが、サブクラスがJavaでそれをオーバーライドしないようにするには、「final」を使用する必要があります
Joachim Sauer '25

167
良い答え-Javaでは "final"の使用法がもう1つあります-ローカル変数またはメソッドパラメーターで再割り当てを防止します。これに相当するc#の直接の対応はありません。
serg10 2009

17
readonlyメンバー変数、コンストラクターで変更できます。pastebin.com
再帰的

8
また、注意:Javaでメンバー変数をfinalとして宣言すると、すべてのコンストラクターがすべてのコードパスで値を割り当てるわけではない場合、コンパイラーは文句を言いますが、C#は読み取り専用メンバー変数を使用したシナリオでのみ警告を発行します
Mene

1
@NickolayKondratyev:はい、私の例は、別のクラスからサブクラス化する必要があるという点で暗黙的でした。本当にインターフェースは必要ありません。それは不必要ですが、それ以外の点では問題ありません。
Noldorin 2013

180

状況によります。

  • ためのfinalクラスまたはメソッド、C#の同等ですsealed
  • 以下のためfinalのフィールド、C#の同等ですreadonly
  • 以下のためにfinalローカル変数やメソッドのパラメータ、は直接C#の同等はありません。

1
実際には、宣言時にfinal変数を割り当てる必要はありません。「最終」とは、変数を参照する前に変数を何らかのコードパスで割り当てる必要があることを意味します。コードパスでは、変数を複数回割り当てることはできません。これはインスタンス変数に適用されます。つまり、コンストラクターは変数を明示的に割り当てる必要があります。
ジェイ

31
+ For a final local variable or method parameter, there's no direct C# equivalent大きな違いがあります。
ダニエルB.チャップマン

1
あなたがいる場合はインスタンス化constのローカル変数のために使用することができます。もちろんfinalを使用すると、宣言と初期化を別々に行うことができる(したがって、値が異なる)ため、同等ではありませんが、知らない場合に備えて...
Griknok

3
const値タイプでのみ使用できます。私が知る限り、ローカル参照型の効果的な定数を作成する方法はありません。
ジョクル

2
@jocull文字列が唯一の例外です。
RaimundKrämer2018

46

ここで欠けているのは、Javaによる最終メンバー変数の明確な割り当ての保証です。

最終メンバー変数Vを持つクラスCの場合、Cのすべてのコンストラクターを通るすべての実行パスは、Vを1回だけ割り当てる必要があります。Vの割り当てに失敗したり、Vを2回以上割り当てると、エラーが発生します。

C#のreadonlyキーワードにはそのような保証はありません。コンパイラーは、readonlyメンバーを未割り当てのままにするか、コンストラクター内で複数回割り当てることを許可します。

したがって、finalとreadonly(少なくともメンバー変数に関して)は明らかに同等ではありません。finalははるかに厳密です。


7

前述したように、sealedfinalメソッドとクラスのと同等です。

残りは複雑です。

  • 以下のためにstatic finalフィールド、static readonly可能最も近いものです。静的コンストラクターで静的フィールドを初期化できます。これは、Javaの静的初期化子によく似ています。これは、定数(プリミティブと不変オブジェクト)と、可変オブジェクトへの定数参照の両方に適用されます。

    const修飾子は、定数のかなり似ていますが、あなたは、静的コンストラクタでそれらを設定することはできません。

  • コンストラクターを離れたら再割り当てしてはいけないフィールドでreadonly使用できます。それは等しくありません- finalコンストラクタまたはイニシャライザでも正確に1つの割り当てが必要です。
  • final私が知っているローカル変数に相当するC#はありません。なぜだれがそれを必要とするのか疑問に思っている場合:if-else、switch-caseなどの前に変数を宣言できます。最終的に宣言することにより、割り当ては最大で1回に制限されます。

    一般に、Javaローカル変数は、読み込まれる前に少なくとも1回割り当てる必要があります。値が読み取られる前に分岐が飛び出さない限り、最終的な変数は1回だけ割り当てられます。これはすべてコンパイル時にチェックされます。これには、エラーに対するマージンが少ない、適切に動作するコードが必要です。

まとめると、C#にはに直接相当するものはありませんfinal。JavaにはC#の優れた機能がいくつかありますが、ほとんどの場合Javaプログラマーとして、C#が同等の機能を提供できない場所を確認することは、私にとっては新鮮です。


6

Javaクラスfinalおよびメソッドfinal->封印。Javaメンバー変数final->ランタイム定数の場合は読み取り専用、コンパイル時定数の場合はconst。

ローカル変数finalとメソッド引数finalに相当するものはありません



0

封印


8
コンテキストに依存し、説明や例を追加することで、回答のその一部のみが助けを必要とする人にとって、より理解しやすくなります
Rune FS
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.