อะไรคือสิ่งที่เทียบเท่าของ Java สุดท้ายใน C #?


559

อะไรคือสิ่งที่เทียบเท่าของ Java finalใน C #?


131
ความคิดเห็นด้านบนของชั้นเรียนว่า "ถ้าคุณแทนที่ชั้นนี้คุณจะถูกไล่ออก!" (ปิดหลักสูตรเรื่องตลกของมัน :)
Hemant

คำตอบ:


861

finalคำหลักที่มีประเพณีหลายอย่างใน Java มันสอดคล้องกับทั้งsealedและreadonlyคำหลักใน C # ขึ้นอยู่กับบริบทที่มีการใช้

การเรียนการสอน

เพื่อป้องกันไม่ให้คลาสย่อย (การสืบทอดจากคลาสที่กำหนด):

ชวา

public final class MyFinalClass {...}

ค#

public sealed class MyFinalClass {...}

วิธีการ

ป้องกันการแทนที่virtualวิธีการ

ชวา

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

ค#

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

เป็นจุดโจอาคิมซาวเออร์ออกความแตกต่างที่โดดเด่นระหว่างสองภาษาที่นี่เป็นที่ Java ด้วยเครื่องหมายเริ่มต้นทุกวิธีไม่คงที่เป็นvirtualในขณะที่ C เครื่องหมาย # sealedพวกเขาเป็น ดังนั้นคุณจะต้องใช้sealedคำหลักใน C # ถ้าคุณต้องการที่จะหยุดการเอาชนะเพิ่มเติมของวิธีการที่ได้รับการทำเครื่องหมายอย่างชัดเจนvirtualในชั้นฐาน

ตัวแปร

หากต้องการอนุญาตให้กำหนดตัวแปรเพียงครั้งเดียว:

ชวา

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

ค#

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

ในฐานะที่เป็นหมายเหตุด้านผลกระทบของreadonlyคำหลักที่แตกต่างจากconstคำหลักในการreadonlyแสดงออกที่มีการประเมินที่รันไทม์มากกว่ารวบรวมเวลาดังนั้นการอนุญาตให้แสดงออกโดยพลการ


15
ฉันจะเพิ่มว่าวิธีการไม่คงที่ทั้งหมดใน Java เป็นเสมือนโดยค่าเริ่มต้น ดังนั้นในขณะที่ใน C # คุณสามารถละทิ้งเสมือนในนิยามแรก ๆ คุณจะต้องใช้ "final" เพื่อหลีกเลี่ยงคลาสย่อยที่แทนที่มันใน Java
Joachim Sauer

166
คำตอบที่ดี - มีอีกหนึ่งการใช้งานของ "final" ใน java แม้ว่า - ในตัวแปรท้องถิ่นหรือพารามิเตอร์วิธีการเพื่อป้องกันไม่ให้กำหนดใหม่ ไม่มีสิ่งนี้เทียบเท่าโดยตรงกับ c #
serg10

17
readonlyตัวแปรสมาชิกสามารถแก้ไขได้ในตัวสร้าง: pastebin.com/AzqzYGiA
เรียกซ้ำ

8
หมายเหตุด้วย: หากคุณประกาศตัวแปรสมาชิกว่าสุดท้ายใน Java คอมไพเลอร์จะบ่นถ้าไม่ใช่คอนสตรัคเตอร์ทุกคนจะกำหนดค่าในทุกเส้นทางของโค้ดในขณะที่ C # จะออกคำเตือนในสถานการณ์นั้นด้วยตัวแปรสมาชิกแบบอ่านอย่างเดียว
Men

1
@NickolayKondratyev: ใช่ฉันเป็นตัวอย่างโดยปริยายว่าคุณต้องทำการ subclassing จากคลาสอื่น คุณไม่ต้องการอินเทอร์เฟซจริงๆ มันฟุ่มเฟือย แต่อย่างอื่นที่ดูถูกต้อง
Noldorin

180

มันขึ้นอยู่กับบริบท

  • สำหรับfinalชั้นเรียนหรือ method, C # sealedเทียบเท่า
  • สำหรับfinalข้อมูลที่C # readonlyเทียบเท่า
  • สำหรับfinalตัวแปรโลคัลหรือพารามิเตอร์เมธอดไม่มีการเทียบเท่า C # โดยตรง

1
ที่จริงแล้วไม่มีข้อกำหนดว่าตัวแปรสุดท้ายจะถูกกำหนดเมื่อมีการประกาศ 'final' หมายถึงตัวแปรต้องได้รับการกำหนดโดยพา ธ ของโค้ดก่อนที่มันจะถูกอ้างถึงและไม่มีโค้ดพา ธ ที่อนุญาตให้ตัวแปรถูกกำหนดมากกว่าหนึ่งครั้ง สิ่งนี้ใช้กับตัวแปรอินสแตนซ์ซึ่งหมายความว่าตัวสร้างต้องกำหนดตัวแปรอย่างชัดเจน
Jay

31
+ สำหรับFor a final local variable or method parameter, there's no direct C# equivalentความแตกต่างที่ยิ่งใหญ่
Daniel B. Chapman

1
หากคุณกำลังอินสแตนซ์ , constสำหรับตัวแปรท้องถิ่นสามารถนำมาใช้ มันไม่เทียบเท่ากันเพราะแน่นอนว่าสุดท้ายจะให้คุณแยกแยะและกำหนดค่าเริ่มต้น (และมีค่าที่ต่างกัน) แต่ในกรณีที่คุณไม่ทราบ ...
Griknok

3
constสามารถใช้ได้กับประเภทค่าเท่านั้น เท่าที่ฉันรู้ไม่มีวิธีที่จะทำให้ค่าคงที่มีประสิทธิภาพสำหรับประเภทการอ้างอิงในท้องถิ่น
กรกฎาคม

2
@jocull ด้วยสตริงเป็นข้อยกเว้นเท่านั้น
Raimund Krämer

46

สิ่งที่ทุกคนที่นี่หายไปคือการรับประกันของ Java ของการกำหนดที่แน่นอนสำหรับตัวแปรสมาชิกสุดท้าย

สำหรับคลาส C ที่มีตัวแปรสมาชิกขั้นสุดท้าย V ทุกเส้นทางการดำเนินการที่เป็นไปได้ผ่านตัวสร้าง C ทุกตัวจะต้องกำหนด V อย่างแน่นอนหนึ่งครั้ง - การไม่กำหนด V หรือการมอบหมาย V สองครั้งขึ้นไปจะส่งผลให้เกิดข้อผิดพลาด

คำหลักแบบอ่านอย่างเดียวของ C # ไม่มีการรับประกันดังกล่าว - คอมไพเลอร์ยินดีที่จะออกจากสมาชิกแบบอ่านอย่างเดียวที่ไม่ได้กำหนดหรืออนุญาตให้คุณกำหนดหลาย ๆ ครั้งภายในคอนสตรัคเตอร์

ดังนั้นสุดท้ายและอ่านได้อย่างเดียว (อย่างน้อยเกี่ยวกับตัวแปรของสมาชิก) ไม่แน่นอนเทียบเท่า - สุดท้ายนั้นเข้มงวดมากขึ้น


7

ดังกล่าวsealedเป็นวิธีการเทียบเท่าfinalและชั้นเรียน

ส่วนที่เหลือมันซับซ้อน

  • สำหรับstatic finalเขตข้อมูลstatic readonlyเป็นสิ่งที่ใกล้เคียงที่สุดที่เป็นไปได้ จะช่วยให้คุณสามารถเริ่มต้นสนามคงที่ในการสร้างคงที่ซึ่งค่อนข้างคล้ายกับเริ่มต้นคงที่ใน Java สิ่งนี้ใช้กับค่าคงที่ (วัตถุพื้นฐานและวัตถุที่ไม่เปลี่ยนรูป) และการอ้างอิงค่าคงที่ไปยังวัตถุที่ไม่แน่นอน

    constปรับปรุงค่อนข้างคล้ายกันสำหรับค่าคงที่ แต่คุณไม่สามารถตั้งไว้ในตัวสร้างแบบคงที่

  • บนฟิลด์ที่ไม่ควรกำหนดใหม่เมื่อออกจาก Constructor readonlyสามารถใช้งานได้ มันไม่เท่ากัน - finalต้องมีหนึ่งการกำหนดแม้ใน constructor หรือ initializer
  • ไม่มีค่าเทียบเท่า C # สำหรับfinalตัวแปรโลคอลที่ฉันรู้จัก หากคุณสงสัยว่าทำไมใครถึงต้องการ: คุณสามารถประกาศตัวแปรก่อน if-else, switch-caseหรือดังนั้น เมื่อประกาศให้เป็นที่สุดคุณจะต้องบังคับใช้ว่าได้รับการมอบหมายให้มากที่สุดครั้งเดียว

    ตัวแปรโลคัล Java โดยทั่วไปจำเป็นต้องกำหนดอย่างน้อยหนึ่งครั้งก่อนที่จะอ่าน ยกเว้นว่าสาขากระโดดก่อนที่จะอ่านค่าตัวแปรสุดท้ายจะถูกกำหนดอย่างแน่นอนหนึ่งครั้ง ทั้งหมดนี้ถูกตรวจสอบเวลาคอมไพล์ ต้องใช้รหัสที่ทำงานได้ดีโดยมีระยะห่างน้อยกว่าสำหรับข้อผิดพลาด

สรุป up, C # finalไม่มีเทียบเท่าโดยตรงของ ในขณะที่ Java ไม่มีคุณสมบัติที่ดีบางอย่างของ C # มันเป็นความสดชื่นสำหรับฉันเป็นส่วนใหญ่โปรแกรมเมอร์ Java เพื่อดูว่า C # ล้มเหลวในการส่งมอบเทียบเท่า


6

Java class final และ method final -> Sealing ตัวแปรสมาชิก Java สุดท้าย -> อ่านได้อย่างเดียวสำหรับค่าคงที่รันไทม์, const สำหรับค่าคงที่เวลารวบรวม

ไม่เทียบเท่าสำหรับ Local Variable final และอาร์กิวเมนต์ method เป็นครั้งสุดท้าย


5

http://en.csharp-online.net/CSharp_FAQ:_What_are_the_differences_between_CSharp_and_Java_constant_declarations

ค่าคงที่ C # ถูกประกาศโดยใช้คีย์เวิร์ด const สำหรับค่าคงที่เวลาคอมไพล์หรือคีย์เวิร์ดแบบอ่านอย่างเดียวสำหรับค่าคงที่รันไทม์ ความหมายของค่าคงที่จะเหมือนกันทั้งในภาษา C # และ Java


0

ที่ปิดผนึก


8
นั่นเป็นเพียงส่วนหนึ่งของคำตอบเพราะมันขึ้นอยู่กับบริบทและการเพิ่มคำอธิบายและ / หรือตัวอย่างจะทำให้ย่อยได้มากขึ้นสำหรับผู้ที่ต้องการความช่วยเหลือ
Rune FS
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.