ฉันพยายามระบุเหตุผลของค่าคงที่ใน Java ฉันได้เรียนรู้ว่า Java ช่วยให้เราประกาศค่าคงที่โดยใช้final
คำหลัก
คำถามของฉันคือทำไม Java ไม่แนะนำคุณลักษณะคงที่ ( const
) เนื่องจากหลายคนบอกว่ามาจาก C ++ ใน C ++ เรามีconst
คำหลัก
กรุณาแบ่งปันความคิดของคุณ
ฉันพยายามระบุเหตุผลของค่าคงที่ใน Java ฉันได้เรียนรู้ว่า Java ช่วยให้เราประกาศค่าคงที่โดยใช้final
คำหลัก
คำถามของฉันคือทำไม Java ไม่แนะนำคุณลักษณะคงที่ ( const
) เนื่องจากหลายคนบอกว่ามาจาก C ++ ใน C ++ เรามีconst
คำหลัก
กรุณาแบ่งปันความคิดของคุณ
คำตอบ:
ทุกครั้งที่ฉันเปลี่ยนจากการเข้ารหัส C ++ ไปเป็นจาวาจะต้องใช้เวลาสักครู่ในการปรับตัวให้เข้ากับการขาดความถูกต้องของภาษาใน Java การใช้งานconst
ใน C ++ นี้แตกต่างจากการประกาศตัวแปรคงที่ถ้าคุณไม่รู้ โดยพื้นฐานแล้วมันช่วยให้มั่นใจว่าวัตถุนั้นไม่สามารถเปลี่ยนแปลงได้เมื่อเข้าถึงผ่านตัวชี้ชนิดพิเศษที่เรียกว่า const-pointer เมื่ออยู่ใน Java ในสถานที่ที่ปกติฉันต้องการคืนค่า const-pointer ฉันกลับไปอ้างอิงด้วยชนิดอินเตอร์เฟส มีวิธีการเท่านั้นที่ไม่ควรมีผลข้างเคียง น่าเสียดายที่สิ่งนี้ไม่ได้ถูกบังคับใช้โดยอีเมล์
Wikipedia เสนอข้อมูลต่อไปนี้ในหัวข้อ:
ที่น่าสนใจคือข้อกำหนดภาษาจาวาถือว่า const เป็นคำหลักที่สงวนไว้ - คือสิ่งที่ไม่สามารถใช้เป็นตัวระบุตัวแปร - แต่ไม่ได้กำหนดซีแมนทิกส์ให้กับมัน มันคิดว่าการจองคำหลักเกิดขึ้นเพื่อให้ส่วนขยายของภาษาจาวารวม C + + - วิธี const สไตล์และชี้ไปที่ประเภท const ตั๋วร้องขอการปรับปรุงในกระบวนการ Java Community สำหรับการใช้ความถูกต้อง const ใน Java ถูกปิดในปี 2005 ซึ่งหมายความว่าการแก้ไขความถูกต้องของ const อาจจะไม่พบทางที่จะนำไปสู่ข้อกำหนดของ Java อย่างเป็นทางการ
final
นั้นคล้ายกัน
final
วิธีการทำงานตัวอย่างแตกต่างจากconst
วิธีC ++ อย่างสิ้นเชิง
final
คำหลักที่เกี่ยวกับคุณสมบัติหรือตัวแปรเพียงเพื่อให้แน่ใจว่าทรัพย์สินหรือตัวแปรที่ได้รับมอบหมายเท่านั้นที่จะครั้งเดียว เรายังคงสามารถเปลี่ยนสถานะของวัตถุนี้โดยการเรียกวิธีการที่มีผลข้างเคียง final
ค่อนข้างคล้ายกันในการจัดสรรสแต็คของ C ++ ในแง่ของการอ้างถึงวัตถุมากกว่าตัวชี้ แต่นั่นคือทั้งหมดที่มันเป็น นี่คือหลักสูตรนอกเหนือจากที่ dom0 พูดไปแล้ว
final
ใน Java ดูเหมือนว่าจะทำงานเหมือน C ++ const
สำหรับประเภทของค่า แต่ก็เหมือน C ++ ที่ไม่ใช่แบบ const T&
สำหรับประเภทการอ้างอิง
อะไรconst
หมายถึง
ครั้งแรกที่ตระหนักดีว่าความหมายของ "const" หมายถึงคำหลักสิ่งที่แตกต่างกับคนที่แตกต่างกัน:
final
- ตัวแปรอ้างอิงไม่สามารถกำหนดใหม่ให้ชี้ไปยังอินสแตนซ์อื่น (ตำแหน่งหน่วยความจำ) แต่อินสแตนซ์นั้นสามารถแก้ไขได้const
/ ซีแมนทิกส์อ้างอิง - หมายถึงการอ้างอิงนี้ไม่สามารถใช้ในการปรับเปลี่ยนอินสแตนซ์ (เช่นไม่สามารถกำหนดให้กับตัวแปรอินสแตนซ์ไม่สามารถเรียกใช้วิธีที่ไม่แน่นอนได้) อินสแตนซ์เดียวกันสามารถแก้ไขอินสแตนซ์ได้ทำไมหรือเพราะเหตุใดไม่ใช่const
วินาทีถ้าคุณต้องการขุดลงในอาร์กิวเมนต์ "pro" vs "con" ให้ดูการอภิปรายภายใต้คำขอ "เพิ่ม" (RFE) RFE นี้ร้องขอคุณลักษณะ "การอ้างอิงแบบอ่านอย่างเดียว" -type "const" เปิดในปี 1999 และจากนั้นปิด / ปฏิเสธโดย Sun ในปี 2005 หัวข้อ "const" ถูกถกเถียงกันอย่างจริงจัง:
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4211070
ในขณะที่มีข้อโต้แย้งที่ดีมากมายทั้งสองด้านเหตุผลบางประการที่อ้างถึง (แต่ไม่จำเป็นต้องมีเหตุผลที่น่าสนใจหรือชัดเจน) กับconst
:
const
หมายถึงด้านบน)ก่อนที่ทุกคนพยายามที่จะมีการอภิปรายเกี่ยวกับว่าผมเหล่านี้จะดีหรือไม่ดีเหตุผลทราบว่าเหล่านี้จะไม่ได้เป็นเหตุผลของผม พวกเขาเป็นเพียง "ส่วนสำคัญ" ของเหตุผลบางอย่างที่ฉันรวบรวมจากการข้ามการอภิปราย RFE ฉันไม่เห็นด้วยกับพวกเขาด้วยตัวเอง - ฉันแค่พยายามอ้างว่าทำไมบางคน (ไม่ใช่ฉัน) อาจรู้สึกว่าconst
คำหลักอาจไม่ใช่ความคิดที่ดี โดยส่วนตัวแล้วฉันชอบความหมาย "const" มากกว่าที่จะแนะนำให้รู้จักกับภาษาในลักษณะที่ไม่คลุมเครือ
volatile
เพื่อให้ง่ายต่อการเข้าใจ? หรือfinal
? Meh
const
ใน C ++ ไม่ได้หมายความว่าค่าเป็นค่าคงที่
const
ใน C ++ หมายความว่าลูกค้าของสัญญารับรองว่าจะไม่เปลี่ยนแปลงมูลค่าของมัน
ไม่ว่าค่าของconst
การเปลี่ยนแปลงการแสดงออกจะเห็นได้ชัดขึ้นถ้าคุณอยู่ในสภาพแวดล้อมที่รองรับการทำงานพร้อมกันตามกระทู้
เนื่องจาก Java ถูกออกแบบมาตั้งแต่เริ่มต้นเพื่อรองรับเธรดและล็อกการทำงานพร้อมกันมันไม่ได้เพิ่มความสับสนโดยการใช้คำมากเกินไปเพื่อให้มีความหมายที่final
มี
เช่น:
#include <iostream>
int main ()
{
volatile const int x = 42;
std::cout << x << std::endl;
*const_cast<int*>(&x) = 7;
std::cout << x << std::endl;
return 0;
}
ออก 42 แล้ว 7
แม้ว่าการx
ทำเครื่องหมายว่าconst
เป็นนามแฝงที่ไม่ใช่ const จะถูกสร้างขึ้น แต่x
ก็ไม่ได้เป็นค่าคงที่ ไม่ใช่คอมไพเลอร์ทุกคนต้องการvolatile
พฤติกรรมนี้ (แม้ว่าคอมไพเลอร์ทุกคนจะได้รับอนุญาตให้อินไลน์ค่าคงที่)
ด้วยระบบที่ซับซ้อนมากขึ้นคุณจะได้นามแฝงแบบ const / non-const โดยไม่ต้องใช้const_cast
ดังนั้นให้คิดว่า const หมายความว่าบางสิ่งจะไม่เปลี่ยนไปกลายเป็นอันตรายมากขึ้นเรื่อย ๆ const
เพียงหมายความว่ารหัสของคุณไม่สามารถเปลี่ยนแปลงได้หากไม่ส่งสัญญาณไม่ใช่ค่าคงที่
const
ไม่ได้หมายความว่าค่าคงที่ หมายความว่าลูกค้าของค่าถูก จำกัด ไม่ให้กลายพันธุ์ ในตัวอย่างของคุณไม่มีนามแฝงดังนั้นผู้ใช้ทั้งหมดจะอยู่ภายใต้ข้อ จำกัด เดียวกัน นี่ไม่ใช่กรณีทั่วไป const
ส่งผลกระทบต่อลูกค้าไม่ใช่ค่า - มันบอกว่าคุณไม่สามารถเปลี่ยนได้ไม่ว่ามันจะไม่เปลี่ยนแปลง
immutable interface
และimmutable object
เป็นอีกวิธีหนึ่ง (เอาชนะกับนักแสดงและการสะท้อน) เพื่อเลียนแบบ const ใน Java "True" const สามารถทำได้ด้วยSealedObjectแต่ก็เป็นการทำลายกรณีการใช้งานของวัตถุของเรา
นี่เป็นคำถามเก่า ๆ แต่ฉันคิดว่าฉันจะสนับสนุน 2 เซ็นต์ของฉันต่อไปตั้งแต่กระทู้นี้มาในการสนทนาวันนี้
นี่ไม่ได้ตอบว่าทำไมไม่มี const? แต่วิธีการที่จะทำให้การเรียนของคุณไม่เปลี่ยนรูป (น่าเสียดายที่ฉันมีชื่อเสียงไม่มากพอที่จะโพสต์เป็นความคิดเห็นต่อคำตอบที่ยอมรับได้)
วิธีที่จะรับประกันการเปลี่ยนแปลงไม่ได้บนวัตถุคือการออกแบบชั้นเรียนของคุณอย่างระมัดระวังมากขึ้นเพื่อไม่เปลี่ยนรูป สิ่งนี้ต้องการความระมัดระวังมากกว่าคลาสที่ไม่แน่นอน
สิ่งนี้จะกลับไปที่รายการJava ที่มีประสิทธิภาพ ของ Josh Bloch 15 - ความไม่แน่นอนลดลง หากคุณยังไม่ได้อ่านหนังสือเล่มนี้รับสำเนาและอ่านมันไปไม่กี่ครั้งผมกล้ารับประกันว่ามันจะขึ้นเป็นรูปเป็นร่างของคุณ"java เกม"
ในรายการที่ 15 Bloch แนะนำว่าคุณควร จำกัด ความไม่แน่นอนของคลาสเพื่อให้แน่ใจว่าสถานะของวัตถุ
หากต้องการอ้างอิงหนังสือโดยตรง:
คลาสที่ไม่เปลี่ยนรูปเป็นเพียงคลาสที่อินสแตนซ์ที่ไม่สามารถแก้ไขได้ ข้อมูลทั้งหมดที่มีอยู่ในแต่ละอินสแตนซ์ถูกจัดเตรียมไว้เมื่อมันถูกสร้างขึ้นและได้รับการแก้ไขสำหรับอายุการใช้งานของวัตถุ ไลบรารีแพลตฟอร์ม Java ประกอบด้วยคลาสที่ไม่เปลี่ยนรูปได้จำนวนมากรวมถึง String คลาสดั้งเดิมที่มีกล่องและ BigInteer และ BigDecimal มีเหตุผลที่ดีมากมายสำหรับสิ่งนี้: คลาสที่ไม่เปลี่ยนรูปนั้นง่ายต่อการออกแบบใช้งานและใช้งานมากกว่าคลาสที่ไม่แน่นอน พวกเขามีแนวโน้มน้อยที่จะเกิดข้อผิดพลาดและมีความปลอดภัยมากขึ้น
จากนั้น Bloch อธิบายวิธีทำให้คลาสของคุณไม่เปลี่ยนรูปโดยทำตาม 5 กฎง่ายๆ:
final
)final
ทำให้ทุกสาขาprivate
ทำให้ทุกสาขาสำหรับรายละเอียดเพิ่มเติมฉันขอแนะนำให้เก็บสำเนาหนังสือ
ความหมายของ C ++ const
นั้นแตกต่างจาก Java final
อย่างมาก หากผู้ออกแบบใช้const
มันจะทำให้สับสนโดยไม่จำเป็น
ความจริงที่ว่าconst
เป็นคำที่สงวนไว้แสดงให้เห็นว่านักออกแบบมีแนวคิดในการนำไปใช้const
แต่พวกเขาตัดสินใจตั้งแต่นั้นมา ดูข้อผิดพลาดที่ปิดนี้ เหตุผลที่ระบุรวมถึงการเพิ่มการรองรับสไตล์ C ++ const
จะทำให้เกิดปัญหาความเข้ากันได้
มีวิธีการสร้างตัวแปร "const" ใน Java แต่สำหรับคลาสที่ระบุเท่านั้น เพียงกำหนดคลาสที่มีคุณสมบัติสุดท้ายและซับคลาสนั้น จากนั้นใช้คลาสฐานที่คุณต้องการใช้ "const" ในทำนองเดียวกันหากคุณต้องการใช้วิธีการ "const" ให้เพิ่มลงในคลาสฐาน คอมไพเลอร์จะไม่อนุญาตให้คุณแก้ไขสิ่งที่คิดว่าเป็นวิธีสุดท้ายของคลาสพื้นฐาน แต่จะอ่านและเรียกเมธอดบนคลาสย่อย
จะมีสองวิธีในการกำหนดค่าคงที่ - const
และstatic final
ด้วยความหมายเดียวกันแน่นอน นอกจากนี้static final
อธิบายพฤติกรรมที่ดีกว่าconst
static
(ไม่ได้เป็นของอินสแตนซ์เฉพาะ) และfinal
- ไม่สามารถเปลี่ยนแปลงได้
คุณสามารถใช้ static final เพื่อสร้างบางสิ่งที่ทำงานคล้ายกับ Const ฉันเคยใช้สิ่งนี้ในอดีต
protected static final int cOTHER = 0;
protected static final int cRPM = 1;
protected static final int cSPEED = 2;
protected static final int cTPS = 3;
protected int DataItemEnum = 0;
public static final int INVALID_PIN = -1;
public static final int LED_PIN = 0;
const
คำหลัก แต่ไม่มีคุณลักษณะพื้นฐาน แก้ไขชื่อและแท็กให้ถูกต้อง