คลาสคงที่ใน java คืออะไร?


94

ฉัน googled หัวข้อนี้ แต่นอกจากWikipediaแล้วฉันไม่พบเอกสารหรือบทความที่เป็นประโยชน์เพิ่มเติม

ใครช่วยอธิบายให้ฉันเข้าใจด้วยคำง่ายๆว่ามันหมายถึงอะไรหรือแนะนำให้ฉันดูเอกสารที่ดีและเข้าใจง่าย


2
+1 สำหรับคำถามเนื่องจากหน้า Wikipedia มีตัวอย่างที่ยอดเยี่ยมจริงๆของสิ่งที่ฉันไม่รู้ว่าคุณทำได้ - มันมีตัวอย่างด้วย คำอธิบายของพวกเขาดีกว่าที่ฉันจะทำให้คุณได้ ค่อนข้างตรงไปตรงมา
iandisme


หากคุณกำลังสนใจในการคง WRT Java บางทีคุณอาจจะให้ความสนใจในการทำสัญญาสำหรับ Java
Mike Samuel

1
คำอธิบายง่ายๆ - < stackoverflow.com/questions/112064/what-is-an-invariant?rq=1 >
ip_x

คำตอบ:


93

มันไม่ได้มีความหมายอะไรโดยเฉพาะในการอ้างอิงถึง java

คลาสคงที่เป็นเพียงคุณสมบัติที่เก็บอินสแตนซ์ทั้งหมดของคลาสเสมอไม่ว่าโค้ดอื่นจะทำอะไรก็ตาม

ตัวอย่างเช่น,

class X {
  final Y y = new Y();
}

X มีค่าคงที่ระดับว่ามีyทรัพย์สินและมันจะไม่และมีค่าของชนิดnullY

class Counter {
  private int x;

  public int count() { return x++; }
}

ล้มเหลวในการรักษาค่าคงที่ที่สำคัญสองตัว

  1. ที่countไม่ส่งคืนค่าลบเนื่องจากอาจมีการไหลน้อยเกินไป
  2. การโทรที่countเพิ่มขึ้นอย่างซ้ำซากจำเจ

คลาสที่แก้ไขจะรักษาค่าคงที่ทั้งสองไว้

class Counter {
  private int x;

  public synchronized int count() {
    if (x == Integer.MAX_VALUE) { throw new IllegalStateException(); }
    return x++;
  }
}

แต่ล้มเหลวในการรักษาค่าคงที่ที่เรียกให้countประสบความสำเร็จตามปกติ (ไม่มีการละเมิด TCB ) เนื่องจากcountอาจทำให้เกิดข้อยกเว้นหรืออาจบล็อกหากเธรดที่หยุดชะงักเป็นเจ้าของจอภาพของตัวนับ

แต่ละภาษาที่มีคลาสทำให้ง่ายต่อการรักษาค่าคงที่ของคลาส แต่ไม่ใช่ภาษาอื่น Java ไม่มีข้อยกเว้น:

  1. คลาส Java มีหรือไม่มีคุณสมบัติและเมธอดอย่างสม่ำเสมอดังนั้นอินเทอร์เฟซอินเทอร์เฟซจึงดูแลรักษาได้ง่าย
  2. คลาส Java สามารถป้องกันprivateฟิลด์ของตนได้ดังนั้นค่าคงที่ที่อาศัยข้อมูลส่วนตัวจึงดูแลรักษาได้ง่าย
  3. คลาส Java สามารถเป็นขั้นสุดท้ายได้ดังนั้นจึงสามารถรักษาค่าคงที่ที่ขึ้นอยู่กับโค้ดที่ละเมิดค่าคงที่โดยการสร้างคลาสย่อยที่เป็นอันตรายได้
  4. Java ช่วยให้nullค่าสามารถแอบได้หลายวิธีดังนั้นจึงเป็นเรื่องยากที่จะรักษาค่าคงที่ "มีค่าจริง"
  5. Java มีเธรดซึ่งหมายความว่าคลาสที่ไม่ซิงโครไนซ์มีปัญหาในการรักษาค่าคงที่ที่อาศัยการดำเนินการตามลำดับในเธรดที่เกิดขึ้นพร้อมกัน
  6. Java มีข้อยกเว้นซึ่งทำให้ง่ายต่อการรักษาค่าคงที่เช่น "ส่งคืนผลลัพธ์ที่มีคุณสมบัติ p หรือไม่ส่งคืนผลลัพธ์" แต่ยากกว่าที่จะรักษาค่าคงที่เช่น "ส่งคืนผลลัพธ์เสมอ"

† - การละเมิดภายนอกหรือTCBคือเหตุการณ์ที่ผู้ออกแบบระบบมองโลกในแง่ดีว่าจะไม่เกิดขึ้น

โดยทั่วไปเราเชื่อว่าฮาร์ดแวร์พื้นฐานทำงานได้ตามที่โฆษณาเมื่อพูดถึงคุณสมบัติของภาษาระดับสูงที่สร้างขึ้นจากภาษาเหล่านี้และข้อโต้แย้งของเราที่มีค่าคงที่ไม่ได้คำนึงถึงความเป็นไปได้ของ:

  • โปรแกรมเมอร์ที่ใช้ debug hooks เพื่อแก้ไขตัวแปรโลคัลเนื่องจากโปรแกรมทำงานในรูปแบบที่โค้ดไม่สามารถทำได้
  • เพื่อนของคุณไม่ได้ใช้การสะท้อนsetAccessibleเพื่อแก้ไขprivateตารางการค้นหา
  • Loki เปลี่ยนแปลงฟิสิกส์ทำให้โปรเซสเซอร์ของคุณเปรียบเทียบตัวเลขสองตัวไม่ถูกต้อง

สำหรับบางระบบ TCB ของเราอาจรวมเฉพาะบางส่วนของระบบดังนั้นเราจึงไม่สามารถสรุปได้

  • ผู้ดูแลระบบหรือดีมอนที่มีสิทธิ์จะไม่ฆ่ากระบวนการ JVM ของเรา

แต่เราอาจสันนิษฐานได้ว่า

  • เราสามารถตรวจสอบไปยังระบบไฟล์ธุรกรรมที่เชื่อถือได้

ยิ่งระบบระดับสูง TCB มักจะมีขนาดใหญ่ขึ้น แต่สิ่งที่ไม่น่าเชื่อถือมากขึ้นคุณสามารถออกจาก TCB ของคุณได้มากเท่าไหร่ก็จะยิ่งมีโอกาสที่ค่าคงที่ของคุณจะคงอยู่ได้มากขึ้นเท่านั้น


2
"ที่countไม่เคยส่งกลับค่าเดิมซ้ำสอง" ถือว่าคลาสไม่แปรผันจริงหรือ
ruakh

1
@ruakh นั่นเป็นคำถามที่ดี ฉันไม่ค่อยแน่ใจนัก สิ่งต่างๆเช่นความเสถียรของ hashCode (สำหรับแต่ละอินสแตนซ์ i, i.hashCode () ไม่เปลี่ยนแปลง) มักเรียกว่า class invariants ซึ่งต้องใช้เหตุผลเกี่ยวกับค่าที่ส่งคืนก่อนหน้านี้ดังนั้นจึงดูสมเหตุสมผลที่จะกล่าวว่า "สำหรับแต่ละอินสแตนซ์ i, i.count () ไม่อยู่ใน (ผลลัพธ์ก่อนหน้าของ i.count ()) "เป็นค่าคงที่ของคลาส
Mike Samuel

@ruakh นั่นคือนิยามที่บริสุทธิ์ไม่ใช่เหรอ? ถ้าฉันตั้งสมมติฐานแบบนี้ไม่แปรผันทำไมไม่? แน่นอนว่าอาจเป็นการรับประกันที่น่าสนใจและสำคัญ (พูดสำหรับการสร้าง ID ที่ไม่ซ้ำกัน) โดยส่วนตัวแล้วฉันยังคิดว่า "ถ้ามีเพียงรหัสเธรดเดียวเท่านั้นที่เข้าถึงคลาสนี้คุณสมบัติต่อไปนี้จะถือ" มีประโยชน์ แต่ฉันไม่แน่ใจว่าเป็นไปได้หรือไม่ที่จะขยายคำจำกัดความในลักษณะที่ต้องถือไว้ในขณะที่แน่นอน เงื่อนไขเป็นจริง (และเมื่อพิจารณาจากการไตร่ตรองโดยพื้นฐานแล้วเป็นไปไม่ได้เลยที่จะรับประกันสิ่งที่น่าสนใจเป็นอย่างอื่น!)
Voo

1
@ruakh - คุณสามารถจำลองเป็นค่าคงที่ของคลาสหรือค่าคงที่ของวิธีการ ไม่ว่าจะด้วยวิธีใดการสร้างแบบจำลองต้องใช้ประวัติแนวคิดของการเรียกใช้เมธอดก่อนหน้านี้บนวัตถุเฉพาะ อันที่จริงคุณสามารถจำลองสิ่งนี้เป็นเงื่อนไขหลังการใช้งานได้ กล่าวคือค่าผลลัพธ์เป็นค่าที่ยังไม่ถูกส่งกลับก่อนหน้านี้
Stephen C

@Voo: Re: "นั่นเป็นคำจำกัดความที่บริสุทธิ์ไม่ใช่เหรอ": แน่นอน แต่เนื่องจากคำถามที่นี่คือ "class invariant" คืออะไร "ฉันคิดว่าคำจำกัดความนั้นเกี่ยวข้อง 100% ดูเหมือนว่าจะดีกว่าในขอบเขตที่เป็นไปได้ที่จะใช้ตัวอย่างที่ชัดเจนหรืออื่น ๆ เพื่อเรียกกรณีที่ไม่ชัดเจนอย่างชัดเจน (ฉันไม่ได้ไม่เห็นด้วยกับตัวอย่าง แต่อย่างใดฉันรู้สึกประหลาดใจกับมันและกำลังถามเพื่อให้แน่ใจ)
ruakh

21

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

ตัวอย่างเช่น,

  1. เงื่อนไขในอาร์กิวเมนต์ของฟังก์ชันคือควรเป็น> 0 (มากกว่าศูนย์) เสมอหรือไม่ควรเป็นโมฆะ
  2. คุณสมบัติ low_account_balance ของสถานะคลาสบัญชีไม่สามารถต่ำกว่า 100 ได้ดังนั้นฟังก์ชันสาธารณะทั้งหมดควรเคารพเงื่อนไขนี้และทำให้แน่ใจว่าคลาสไม่แปรผัน
  3. การอ้างอิงตามกฎระหว่างตัวแปรนั่นคือค่าของตัวแปรหนึ่งขึ้นอยู่กับอีกตัวแปรหนึ่งดังนั้นหากตัวแปรหนึ่งเปลี่ยนแปลงโดยใช้กฎการแก้ไขบางตัวตัวแปรอื่น ๆ ก็ต้องเปลี่ยนเช่นกัน ต้องรักษาความสัมพันธ์ระหว่าง 2 ตัวแปรนี้ไว้ หากไม่เป็นเช่นนั้นแสดงว่าค่าคงที่ถูกละเมิด

11

เป็นข้อเท็จจริงที่ต้องเป็นจริงเกี่ยวกับคลาสอินสแตนซ์ ตัวอย่างเช่นถ้าคลาสมีคุณสมบัติ X และค่าคงที่สามารถเป็น X ต้องมากกว่า 0 สำหรับความรู้ของฉันไม่มีวิธีการในตัวในการรักษาค่าคงที่คุณต้องทำให้คุณสมบัติเป็นส่วนตัวและตรวจสอบให้แน่ใจว่า getters และ setters ของคุณบังคับใช้คุณสมบัติที่ไม่แปรเปลี่ยน

มีคำอธิบายประกอบที่สามารถตรวจสอบคุณสมบัติโดยใช้การสะท้อนและตัวสกัดกั้น http://docs.oracle.com/javaee/7/api/javax/validation/constraints/package-summary.html

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