Apakah ada alasan inisialisasi malas tidak dapat dibangun ke Jawa?

10

Karena saya bekerja pada server yang sama sekali tidak memiliki status non-persisten untuk pengguna, setiap objek terkait Pengguna yang kami miliki diluncurkan pada setiap permintaan.

Akibatnya saya sering menemukan diri saya melakukan inisialisasi malas dari properti objek yang mungkin tidak digunakan.

protected EventDispatcher dispatcher = new EventDispatcher();

Menjadi...

protected EventDispatcher<EventMessage> dispatcher;

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

Apakah ada alasan ini tidak dapat dibangun ke Jawa?

protected lazy EventDispatcher dispatcher = new EventDispatcher();


Seperti yang disebutkan di bawah dalam komentar, saya menyadari bahwa bahasa secara teori dapat berevolusi untuk memasukkan sebagian besar apa pun yang Anda inginkan. Saya mencari ukuran praktis dari kemungkinan. Apakah ini akan bertentangan dengan fitur lain? Apakah implementasinya cukup sederhana untuk bekerja dengan baik dengan JVM seperti yang ada? Dan bahkan, apakah itu ide yang bagus?

Nicole
sumber
2
tidak tahu tetapi kode contoh tidak aman
Armand
2
@Alison synchronizedkata kunci akan bekerja sama seperti jika itu pada metode. Saya membayangkan akan ada beberapa akomodasi metode konstruksi yang lebih rumit. Dalam kasus penggunaan khusus saya , karena sifat masalahnya, dengan setiap permintaan sebagai dunianya sendiri, sinkronisasi tidak ada gunanya.
Nicole
Di C # Lazy ada di perpustakaan, tetapi didukung oleh bahasa. sankarsan.wordpress.com/2009/10/04/laziness-in-c-4-0-lazyt Apakah Jawa memiliki lambdas dan delegasi serta penutupan? Omong-omong, Anda memang ingin menanyakan ini di SO, sehingga Jon Skeet & co. dapat berbagi kebijaksanaan mereka.
Pekerjaan
3
Anda dapat membangun hampir semua hal ke dalam bahasa apa pun. Tetapi anggaran kompleksitas dan daftar fitur terbatas dan perancang bahasa hanya dapat memasukkan apa yang mereka anggap paling penting (well, kecuali Larry Wall - terutama di Perl 6 alias "Semua paradigma Anda adalah milik kami.").
1
Masalah mendasarnya adalah bahwa Java adalah satu-satunya bahasa yang diketik secara statis tanpa fasilitas pemrograman meta. Dalam C Anda bisa menulis ini sebagai makro dalam sepuluh menit. Di C ++ Anda bisa menulis ini sebagai templat dalam waktu sekitar dua menit. Di Jawa, Anda dapat ... menempel dan memodifikasi.
kevin cline

Jawaban:

14

Ini jawaban delapan halaman untuk pertanyaan Anda: http://tinlizzie.org/~awarth/papers/fool07.pdf

Jika saya dapat mencoba dan meringkas masalah secara kasar dengan menambahkan kemalasan, ini adalah kasus sudut. Ada banyak peringatan di sekitar efek samping. Pertimbangkan, dalam contoh Anda, jika konstruktor memiliki efek samping yang terlihat seperti menabrak penghitung global atau melakukan I / O ... Sulit untuk memikirkan kapan itu akan terjadi. Atau pertimbangkan efek samping yang bahkan lebih buruk tentang pengecualian (mereka dilemparkan ... ketika Anda merujuk objek malas?)

Langsung saja ke bagian 6 di kertas di atas. (Dan kagumi semua logika formal tipe sistem pada halaman yang Anda lewati ...)

PT
sumber
Menerima jawaban ini karena dalamnya makalah yang membahas fitur ini. Terima kasih!
Nicole
TL; DR ketika Anda memprogram Anda harus tahu apa yang terjadi untuk mencegah efek samping, dengan malas, ini benar-benar dapat membantu Anda. Jika Anda tahu Hibernate dan seberapa banyak masalah yang dialami beberapa orang, bayangkan saja hal yang sama untuk seluruh bahasa.
Walfrat
10

Tentu saja sangat mungkin. Bahkan, scala sudah memiliki fitur ini! (Scala adalah bahasa JVM dan dikompilasi ke bytecode). Berikut ini adalah sumber skala:

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

Dan inilah bentuk peralihan dari kode yang dikompilasi:

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();
      ()
    }
  }

}

oxbow_lakes
sumber
Jadi bagaimana ini akan berdamai dengan jawaban PT di programmers.stackexchange.com/a/110958/24257 ?
Pacerier
6

Saya pikir Anda pertama-tama perlu menambahkan properti nyata ke langauge Java, daripada mengandalkan idiom getX / setX. Dengan begitu Anda bisa menandai properti sebagai malas (dan disinkronkan, hanya baca dll ...).

Semacam apa yang diminta di sini (Objective-C, tetapi konsep berlaku).

Martin Wickman
sumber
0

Tentu saja ini dapat ditambahkan ke Jawa, kata kunci lazy dapat diimplementasikan sebagai gula sintaksis. Namun, apakah itu akan dilaksanakan tergantung pada visi pembangun kompiler.

Michiel Overeem
sumber