มีเหตุผลใดที่การเริ่มต้นแบบขี้เกียจไม่สามารถสร้างใน Java ได้หรือไม่?


10

เนื่องจากฉันกำลังทำงานบนเซิร์ฟเวอร์ที่ไม่มีสถานะที่ไม่คงที่สำหรับผู้ใช้ทุกออบเจ็กต์ที่เกี่ยวข้องกับผู้ใช้ที่เรามีจะถูกนำเสนอในทุกคำขอ

ดังนั้นฉันมักจะพบว่าตัวเองกำลังเริ่มต้นขี้เกียจของคุณสมบัติของวัตถุที่อาจไม่ได้ใช้

protected EventDispatcher dispatcher = new EventDispatcher();

กลายเป็น...

protected EventDispatcher<EventMessage> dispatcher;

public EventDispatcher<EventMessage> getEventDispatcher() {
    if (dispatcher == null) {
        dispatcher = new EventDispatcher<EventMessage>();
    }
    return dispatcher;
}

มีเหตุผลใดที่สิ่งนี้ไม่สามารถสร้างใน Java ได้หรือไม่?

protected lazy EventDispatcher dispatcher = new EventDispatcher();


ตามที่ระบุไว้ด้านล่างในความคิดเห็นฉันรู้ว่าภาษาอาจมีวิวัฒนาการทางทฤษฎีที่จะรวมทุกอย่างที่คุณต้องการ ฉันกำลังมองหาการวัดความเป็นไปได้ในทางปฏิบัติ สิ่งนี้ขัดแย้งกับฟีเจอร์อื่นหรือไม่ การใช้งานง่ายพอที่จะทำงานได้ดีกับ JVM หรือไม่ และเป็นความคิดที่ดีหรือไม่?


2
dunno แต่โค้ดตัวอย่างไม่ปลอดภัยสำหรับเธรด
Armand

2
@Alison synchronizedคำหลักจะทำงานเหมือนกับว่าเป็นวิธีการ ฉันคิดว่าจะมีวิธีการก่อสร้างที่ซับซ้อนมากขึ้น ในกรณีการใช้งานเฉพาะของฉันเนื่องจากลักษณะของปัญหาทุกครั้งที่มีการร้องขอในโลกของตัวเองการซิงโครไนซ์นั้นไม่มีจุดหมาย
นิโคล

ใน C # Lazy อยู่ในไลบรารี แต่ได้รับการสนับสนุนโดยภาษา sankarsan.wordpress.com/2009/10/04/laziness-in-c-4-0-lazyt Java มี lambdas และผู้ได้รับมอบหมายและการปิดหรือไม่? อย่างไรก็ตามคุณต้องการถามเรื่องนี้กับ SO ดังนั้น Jon Skeet & co สามารถแบ่งปันภูมิปัญญาของพวกเขา
งาน

3
คุณสามารถสร้างทุกอย่างสวยเป็นภาษาใด ๆ แต่งบประมาณความซับซ้อนและรายการคุณสมบัติมี จำกัด และนักออกแบบภาษาสามารถรวมสิ่งที่พวกเขาเห็นว่าสำคัญที่สุดเท่านั้น (ยกเว้น Larry Wall - โดยเฉพาะใน Perl 6 หรือที่รู้จักกันว่า "กระบวนทัศน์ทั้งหมดของคุณเป็นของเรา")

1
ปัญหาพื้นฐานคือ Java เป็นภาษาเกี่ยวกับภาษาที่พิมพ์แบบคงที่เท่านั้นโดยไม่มีเครื่องมือการเขียนโปรแกรมเมตา ใน C คุณสามารถเขียนสิ่งนี้เป็นมาโครได้ในสิบนาที ใน C ++ คุณสามารถเขียนสิ่งนี้เป็นเทมเพลตในเวลาประมาณสองนาที ใน Java คุณสามารถ ... วางและแก้ไข
วินไคลน์

คำตอบ:


14

นี่คือคำตอบสำหรับคำถามของคุณแปดหน้า: http://tinlizzie.org/~awarth/papers/fool07.pdf

ถ้าฉันสามารถลองสรุปปัญหาอย่างคร่าว ๆ กับการเพิ่มความเกียจคร้านได้นั่นเป็นมุมของกรณี มีข้อแม้มากมายรอบผลข้างเคียง ลองพิจารณาในตัวอย่างของคุณถ้าคอนสตรัคมีผลข้างเคียงที่มองเห็นได้เช่นการชนเคาน์เตอร์ทั่วโลกหรือทำ I / O ... มันยากที่จะให้เหตุผลว่าจะเกิดอะไรขึ้น หรือพิจารณาถึงผลข้างเคียงที่น่าเกลียดเกี่ยวกับข้อยกเว้น (มันถูกโยนทิ้ง ... เมื่อคุณอ้างอิงวัตถุขี้เกียจ?)

เพียงข้ามไปที่หัวข้อ 6 ในกระดาษด้านบน (และชื่นชมตรรกะอย่างเป็นทางการของระบบทุกประเภทในหน้าเว็บที่คุณข้าม ... )


ยอมรับคำตอบนี้เนื่องจากความลึกของกระดาษที่ระบุคุณสมบัตินี้ ขอบคุณ!
นิโคล

TL; DR เมื่อคุณโปรแกรมคุณต้องรู้ว่าจะเกิดอะไรขึ้นเพื่อป้องกันผลข้างเคียงด้วยความขี้เกียจสิ่งนี้จะช่วยให้คุณมีมือได้อย่างแท้จริง หากคุณรู้จักไฮเบอร์เนตและมีปัญหากับคนมากแค่ไหนลองนึกภาพเหมือนกันสำหรับทั้งภาษา
Walfrat

10

แน่นอนมันเป็นไปได้อย่างชัดเจน ในความเป็นจริงสกาล่ามีคุณสมบัตินี้อยู่แล้ว! (Scala เป็นภาษา JVM และคอมไพล์ลงใน bytecode) นี่คือส่วนหนึ่งของแหล่งสกาล่า:

class Foo {
  lazy val bar = "Hello World"
}

และนี่คือรูปแบบกลางของรหัสที่รวบรวมดูเหมือน:

scalac -Xprint:icode Foo.scala

[[syntax trees at end of icode]]// Scala source: Foo.scala
package <empty> {
  class Foo extends java.lang.Object with ScalaObject {
    @volatile protected var bitmap$0: Int = 0;
    lazy private[this] var bar: java.lang.String = _;
    <stable> <accessor> lazy def bar(): java.lang.String = {
      if (Foo.this.bitmap$0.&(1).==(0))
        {
          Foo.this.synchronized({
            if (Foo.this.bitmap$0.&(1).==(0))
              {
                Foo.this.bar = "Hello World";
                Foo.this.bitmap$0 = Foo.this.bitmap$0.|(1);
                ()
              };
            scala.runtime.BoxedUnit.UNIT
          });
          ()
        };
      Foo.this.bar
    };
    def this(): Foo = {
      Foo.super.this();
      ()
    }
  }

}


ดังนั้นวิธีที่จะตกลงกันได้นี้กับคำตอบ PT ที่programmers.stackexchange.com/a/110958/24257 ?
Pacerier

6

ฉันคิดว่าคุณต้องเพิ่มคุณสมบัติจริง ๆ ลงในจาวาสคริปต์ชวามากกว่าพึ่งพาพึ่งพา getX / setX idiom ด้วยวิธีนี้คุณสามารถทำเครื่องหมายว่าทรัพย์สินขี้เกียจ (และซิงโครไนซ์อ่านอย่างเดียว ฯลฯ ... )

เรียงลำดับของสิ่งที่ถูกถามที่นี่ (Objective-C แต่ใช้แนวคิด)


0

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

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