Apa yang setara dengan final Java di C #?

560

Apa yang setara dengan Java finaldi C #?

Nosrama
sumber
131
Sebuah komentar di atas kelas mengatakan "Jika Anda menimpa kelas ini, Anda dipecat!" (tentunya lelucon nya :)
Hemant

Jawaban:

861

Kata finalkunci memiliki beberapa penggunaan di Jawa. Ini sesuai dengan kata kunci sealeddan readonlydalam C #, tergantung pada konteks di mana ia digunakan.

Kelas

Untuk mencegah subclassing (warisan dari kelas yang ditentukan):

Jawa

public final class MyFinalClass {...}

C #

public sealed class MyFinalClass {...}

Metode

Cegah pengubahan virtualmetode.

Jawa

public class MyClass
{
    public final void myFinalMethod() {...}
}

C #

public class MyClass : MyBaseClass
{
    public sealed override void MyFinalMethod() {...}
}

Seperti yang ditunjukkan oleh Joachim Sauer, perbedaan penting antara kedua bahasa di sini adalah bahwa Java secara default menandai semua metode non-statis virtual, sedangkan C # menandai mereka sebagai sealed. Oleh karena itu, Anda hanya perlu menggunakan sealedkata kunci dalam C # jika Anda ingin berhenti menimpa metode yang telah ditandai secara eksplisit virtualdi kelas dasar.

Variabel

Untuk hanya mengizinkan variabel ditugaskan satu kali:

Jawa

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

C #

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

Sebagai catatan tambahan, efek dari readonlykata kunci berbeda dari constkata kunci di mana readonlyekspresi dievaluasi pada saat runtime daripada waktu kompilasi , sehingga memungkinkan ekspresi sewenang-wenang.

Noldorin
sumber
15
Saya akan menambahkan bahwa semua metode non-statis di Jawa adalah virtual secara default. Jadi sementara di C # Anda dapat meninggalkan virtual dalam definisi awal, Anda harus menggunakan "final" untuk menghindari subclass yang menimpanya di Jawa
Joachim Sauer
167
jawaban yang bagus - ada satu lagi penggunaan "final" di java - pada variabel lokal atau parameter metode untuk mencegah penugasan kembali. Tidak ada yang setara dengan c #.
serg10
17
readonlyvariabel anggota dapat dimodifikasi dalam konstruktor: pastebin.com/AzqzYGiA
rekursif
8
Perhatikan juga: Jika Anda mendeklarasikan variabel anggota sebagai final di Jawa, kompiler akan mengeluh, jika tidak setiap konstruktor memberikan nilai di setiap jalur kode, sementara C # hanya mengeluarkan peringatan dalam skenario itu dengan variabel anggota yang hanya baca
Mene
1
@NickolayKondratyev: Yap, contoh saya tersirat dalam bahwa Anda harus subkelas dari kelas lain. Anda tidak benar-benar membutuhkan antarmuka; itu berlebihan, tetapi sebaliknya itu terlihat benar.
Noldorin
180

Itu tergantung pada konteksnya.

LukeH
sumber
1
Sebenarnya tidak ada persyaratan untuk menentukan variabel final saat dideklarasikan. 'final' berarti bahwa variabel harus ditetapkan oleh beberapa jalur kode sebelum direferensikan dan tidak ada jalur kode yang memungkinkan variabel untuk ditugaskan lebih dari satu kali. Ini berlaku untuk variabel instan, yang pada dasarnya berarti bahwa konstruktor harus menetapkan variabel secara eksplisit.
Jay
31
+ untuk For a final local variable or method parameter, there's no direct C# equivalentperbedaan besar.
Daniel B. Chapman
1
Jika Anda instantiating , const untuk variabel lokal dapat digunakan. Ini tidak setara karena tentu saja final memungkinkan Anda secara terpisah mendeklarasikan dan menginisialisasi (dan memiliki nilai yang berbeda), tetapi jika Anda tidak tahu ...
Griknok
3
consthanya dapat digunakan pada tipe nilai. Sejauh yang saya tahu tidak ada cara untuk membuat konstanta yang efektif untuk tipe referensi lokal.
jocull
2
@ jocull Dengan string adalah satu-satunya pengecualian.
Raimund Krämer
46

Apa yang tidak ada di semua orang di sini adalah jaminan Java atas penugasan yang pasti untuk variabel anggota akhir.

Untuk kelas C dengan variabel anggota akhir V, setiap jalur eksekusi yang mungkin melalui setiap konstruktor C harus menetapkan V tepat sekali - gagal menetapkan V atau menetapkan V dua atau lebih kali akan menghasilkan kesalahan.

Kata kunci hanya-baca C # tidak memiliki jaminan seperti itu - kompiler lebih dari senang untuk membiarkan anggota yang hanya dibaca tidak ditugaskan atau memungkinkan Anda untuk menetapkannya beberapa kali dalam konstruktor.

Jadi, final dan readonly (setidaknya sehubungan dengan variabel anggota) jelas tidak setara - final jauh lebih ketat.

Beberapa pria
sumber
7

Seperti yang disebutkan, sealedsetara finaldengan metode dan kelas.

Sedangkan sisanya, itu rumit.

  • Untuk static finalbidang, static readonlyadalah hal terdekat yang mungkin. Ini memungkinkan Anda untuk menginisialisasi bidang statis dalam konstruktor statis, yang cukup mirip dengan penginisialisasi statis di Jawa. Ini berlaku untuk konstanta (primitif dan objek tidak berubah) dan referensi konstan untuk objek bisa berubah.

    The constpengubah cukup mirip untuk konstanta, tetapi Anda tidak dapat mengatur mereka dalam konstruktor statis.

  • Pada bidang yang tidak boleh dipindahkan setelah meninggalkan konstruktor, readonlydapat digunakan. Itu tidak sama meskipun - finalmembutuhkan tepat satu tugas bahkan dalam konstruktor atau penginisialisasi.
  • Tidak ada yang setara dengan C # untuk finalvariabel lokal yang saya ketahui. Jika Anda bertanya-tanya mengapa ada orang yang membutuhkannya: Anda dapat mendeklarasikan variabel sebelum if-else, switch-case atau lebih. Dengan menyatakan itu final, Anda menegaskan bahwa itu ditetapkan paling banyak satu kali.

    Variabel lokal Java secara umum harus ditugaskan setidaknya satu kali sebelum dibaca. Kecuali jika cabang melompat sebelum nilai dibaca, variabel terakhir ditetapkan tepat sekali. Semua ini diperiksa waktu kompilasi. Ini membutuhkan kode berperilaku baik dengan sedikit margin untuk kesalahan.

Disimpulkan, C # tidak memiliki padanan langsung dengan final. Sementara Java tidak memiliki beberapa fitur bagus dari C #, itu menyegarkan bagi saya karena kebanyakan programmer Java untuk melihat di mana C # gagal untuk memberikan yang setara.

Vlasec
sumber
6

Final kelas Java dan metode final -> disegel. Final variabel anggota Java -> hanya untuk konstanta runtime, const untuk konstanta waktu kompilasi.

Tidak ada padanan untuk final Variabel Lokal dan argumen metode akhir

Vijayakumarpl
sumber
0

tertutup

x2.
sumber
8
Itu hanya bagian dari jawaban karena tergantung pada konteks dan menambahkan penjelasan dan / atau contoh akan membuatnya lebih mudah dicerna bagi mereka yang membutuhkan bantuan
Rune FS