enum.values ​​() - คือลำดับของการกำหนดค่า enums ที่ส่งคืน


105

ฉันมี enum SOME_ENUM:

public enum SOME_ENUM {
  EN_ONE,
  EN_TWO,
  EN_THREE;
}

จะSOME_ENUM.values()ส่งคืน enum ตามลำดับการประกาศ enum เสมอ: EN_ONE, EN_TWO, EN_THREE? เป็นกฎหรือไม่รับประกันว่าจะไม่มีการเปลี่ยนแปลงใน JDK รุ่นถัดไป?


1
ฉันวนซ้ำ enum ของฉันเพื่อเติมรายการซึ่งมากกว่าที่อื่นในรหัสฉันอ่านซ้ำใน enum นี้
Skarab

11
@MitchWheat ด้วยเหตุผลเดียวกับที่คุณต้องพึ่งพาลำดับการสงวนลิสต์: เนื่องจาก JDK เป็นเครื่องมือที่ให้การรับประกันบางอย่างแก่คุณและการใช้การค้ำประกันเหล่านี้จะช่วยให้คุณเขียนโค้ดได้กระชับและดีขึ้น เป็นที่ยอมรับคำถาม "รับประกันว่าจะไม่เปลี่ยนแปลงหรือไม่" เป็นไปไม่ได้ที่จะตอบคุณไม่สามารถวางใจได้อย่างแน่นอนไม่มีอะไรรับประกันได้
Fletch

คำตอบ:


144

ข้อกำหนดภาษา Java ใช้ภาษาที่ชัดเจนนี้:

@ ส่งคืนอาร์เรย์ที่มีค่าคงที่ของประเภท enum นี้ตามลำดับที่ประกาศ[Source]

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


1
หากมีคนเพิ่มค่าตรงกลางในโค้ดรุ่นที่ใหม่กว่าสิ่งนี้อาจทำให้คุณล้มเหลวได้เนื่องจากจะเปลี่ยนค่าลำดับขององค์ประกอบอื่น ๆ (ดูวิธี Enum.ordinal ()) ไม่ควรใช้ตำแหน่งลำดับเป็นกลไกอนุกรม (เช่นอย่าเก็บไว้ในฐานข้อมูล) ด้วยเหตุนี้
Matt

1
ลิงก์ไปยังแหล่งที่มาของข้อกำหนดนั้นหรือไม่
Dan Grahn


16

ใช่รับประกันว่าจะส่งคืนตามลำดับนั้น

อย่างไรก็ตามคุณควรหลีกเลี่ยงการพึ่งพาสิ่งนั้นและordinal()ค่าเนื่องจากสามารถเปลี่ยนแปลงได้หลังจากแทรกรายการใหม่เป็นต้น


+1 สำหรับคำแนะนำปราชญ์ ในหัวข้อ ordinal () Effective Java แนะนำให้เพิ่มฟิลด์สมาชิกในชนิด enum
ide

9

มันจะถูกกำหนดโดยการสั่งซื้อค่าของคุณมีการประกาศใน. แต่ไม่มีการรับประกันว่าคุณ (หรือคนอื่น) จะไม่สั่งซื้อ / แทรก / ลบค่าในอนาคต ดังนั้นคุณไม่ควรพึ่งพาคำสั่ง

Java ที่มีประสิทธิภาพ 2nd Edition อุทิศ Item 31 ให้กับหัวข้อที่เกี่ยวข้องอย่างใกล้ชิด: ใช้ช่องอินสแตนซ์แทนลำดับ :

ห้ามหาค่าที่เกี่ยวข้องกับ enum จากลำดับของมัน เก็บไว้ในช่องอินสแตนซ์แทน


3
"ไม่รับประกันว่าจะไม่มีใครจัดลำดับค่าใหม่ในอนาคต" - แต่นั่นเป็นเหตุผลว่าทำไมฉันจึงต้องพึ่งพาคำสั่ง :-)! ฉันต้องการสั่งซื้อรายการใหม่ในอนาคตและด้วยเหตุนี้จึงเปลี่ยนพฤติกรรมของโปรแกรมของฉัน Bloch ถูกต้องเกี่ยวกับการไม่พึ่งพาลำดับและถ้าตัวอย่างของผู้ถามเกี่ยวข้องกับ enums เช่น EN_TWO จริงๆเขาก็อาศัยลำดับและไม่ควรทำเช่นนี้ แต่การพึ่งพาคำสั่งนั้นเป็นเรื่องปกติดี ในความเป็นจริงตามคำสั่งรับประกันในการสร้างฟิลด์เฉพาะสำหรับคำสั่งจะเป็นการเขียนโค้ดซ้ำซ้อนหนังสือประเภทอย่าง Effective Java บอกให้คุณไม่ต้องทำ
Fletch

@ เฟลตช์ขอโทษฉันไม่ค่อยได้ติดตามคุณ สำหรับฉันดูเหมือนว่าคุณกำลังพยายามใช้enumเพื่อจุดประสงค์บางอย่างที่ไม่ได้มีไว้สำหรับ
PéterTörök

สมมติว่าคุณมี "ดาวเคราะห์" ที่มีชื่อเสียง ใน UI ของคุณคุณต้องการแสดงรายการดาวเคราะห์ตามลำดับระยะห่างจากดวงอาทิตย์ คุณจะบรรลุสิ่งนี้ได้อย่างไร? ฉันจะเรียงลำดับค่าคงที่ของดาวเคราะห์ตามลำดับที่ถูกต้องภายในคลาส enum จากนั้นจึงแจกแจง enum ใน UI เนื่องจากคำสั่งนั้นเชื่อถือได้สิ่งนี้จะได้ผล นั่นคือสิ่งที่ฉันกำลังพูดถึง หากวันหนึ่งโลกเคลื่อนเข้าใกล้ดวงอาทิตย์มากกว่าดาวอังคารแน่นอนว่าในช่วงเวลาดังกล่าวสิ่งแรกในจิตใจที่อบอุ่นของคุณคือการรักษารหัสของคุณ! ดังนั้นคุณจึงไปที่ชั้นเรียน Planet ของคุณและย้าย EARTH ไปก่อน MARS
Fletch

@ เฟลทช์โลกอยู่ใกล้ดวงอาทิตย์มากกว่าดาวอังคารแล้ว ;-) แต่ฉันเข้าใจว่าคุณหมายถึงอะไร อย่างไรก็ตามในกรณีนี้ลำดับของดาวเคราะห์เป็นฟังก์ชันของระยะห่างเฉลี่ยจากดวงอาทิตย์ซึ่งไม่ใช่ลำดับที่เรียบง่ายดังนั้น IMHO จึงควรจัดเก็บเป็นเขตข้อมูลที่แตกต่างกันสำหรับดาวเคราะห์แต่ละดวง จากนั้นคุณสามารถมีเครื่องเปรียบเทียบเล็กน้อยเพื่อเปรียบเทียบดาวเคราะห์ตามระยะทางเฉลี่ยจากดวงอาทิตย์และจัดลำดับโดยใช้ตัวเปรียบเทียบนี้ นี่คือ IMHO เป็นโซลูชันที่สะอาดและไม่สามารถเข้าใจผิดได้ ในขณะที่วิธีการแก้ปัญหาของคุณแตกทันทีที่เช่นเพื่อนร่วมงานคนใหม่ตัดสินใจว่าดาวเคราะห์ควรอยู่ในรายการตามลำดับตัวอักษรอย่างชัดเจน ;-)
PéterTörök

1
ฮ่าฮ่าฮ่าอืมใช่แล้วมันเป็นแผนการสมรู้ร่วมคิดทั้งหมดไม่มีดาวอังคาร ตอนแรกฉันจะใช้ดาวเสาร์ แต่จำไม่ได้ว่าดาวเคราะห์ดวงไหนอยู่ใกล้ แต่แผนของดาวอังคารดูเหมือนว่าจะมีผลย้อนกลับ :-) อย่างไรก็ตาม ... ในกรณีนี้ตัวเปรียบเทียบจะดี แต่มีข้อเสียคือต้องใช้รหัสมากขึ้นอย่างเห็นได้ชัด ฉันคิดว่าหากคุณอาศัยการเรียงลำดับซอร์สโค้ดการบันทึกสิ่งนี้ในความคิดเห็นของชั้นเรียนจะเป็นเรื่องที่ดี เพื่อนร่วมงานของคุณอาจอ่านด้วยซ้ำ
Fletch

7

คำตอบอื่น ๆ นั้นดี แต่อย่าแสดงความคิดเห็นเกี่ยวกับสิ่งนี้:

"เป็นกฎหรือไม่รับประกันว่าจะไม่มีการเปลี่ยนแปลงในรุ่นถัดไปของ Jdk"

ฉันไม่เชื่อว่าจะมีการค้ำประกัน JDK ในอนาคตดังนั้นคุณไม่ควรกังวลเกี่ยวกับเรื่องนี้ด้วยซ้ำ จะไม่มีทางบังคับพวกเขาได้ผู้นำ JDK ในอนาคตอาจตัดสินใจหักหลังในการค้ำประกันดังกล่าว มันเหมือนกับระบบรัฐสภาของเวสต์มินสเตอร์: "ไม่มีรัฐสภาใดสามารถผูกมัดรัฐสภาในอนาคตได้"

กล่าวได้ว่าประวัติศาสตร์ของ JDK แสดงให้เห็นถึงความสอดคล้องที่ดีเยี่ยม พวกเขาไม่ได้ทำการเปลี่ยนแปลงที่ไม่สมบูรณ์มากนักดังนั้นคุณจึงมั่นใจได้ว่าพฤติกรรมที่ระบุในปัจจุบัน(ไม่ใช่แค่สังเกต) จะได้รับการรักษาไว้

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