10

Since I'm working on a server with absolutely no non-persisted state for users, every User-related object we have is rolled out on every request.

Consequently I often find myself doing lazy initialization of properties of objects that may go unused.

protected EventDispatcher dispatcher = new EventDispatcher();

Becomes...

protected EventDispatcher<EventMessage> dispatcher;

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

Is there any reason this couldn't be built into Java?

protected lazy EventDispatcher dispatcher = new EventDispatcher();


As mentioned below in the comments, I realize a language could theoretically evolve to include most anything you want. I'm looking for a practical measurement of possibility. Would this conflict with other features? Is the implementation simple enough to work well with the JVM as it exists? And even, is it a good idea?

  • 2
    dunno but example code isn't thread-safe – Armand Feb 19 '11 at 2:03
  • 2
    @Alison the synchronized keyword would work the same as if it was on the method. I imagine there would be some accomodation of more complicated construction methods. In my specific use case, due to the nature of the problem, with every request as it's own world, synchronized is pointless. – Nicole Feb 19 '11 at 2:09
  • In C# Lazy is in a library, but it is supported by the language. sankarsan.wordpress.com/2009/10/04/laziness-in-c-4-0-lazyt Does Java have lambdas and delegates and closures? By the way, you do want to ask this on SO, so that Jon Skeet & co. can share their wisdom. – Job Feb 19 '11 at 4:25
  • 3
    You can build pretty much everything into any language. But complexity budget and feature list are limited and the language designers can only include what they consider most important (well, except Larry Wall - especially in Perl 6 aka "All your paradigms are belong to us."). – user7043 Feb 19 '11 at 11:43
  • 1
    The fundamental problem is that Java is about the only statically typed language with no meta-programming facility. In C you could write this as a macro in ten minutes. In C++ you could write this as a template in about two minutes. In Java you can ... paste and modify. – kevin cline Sep 27 '11 at 7:29
14
+50

Here is an eight page answer to your question: http://tinlizzie.org/~awarth/papers/fool07.pdf

If i can try and coarsely summarize the problems with adding laziness, it's the corner cases. There are a lot of caveats around side-effects. Consider, in your example, if the constructor had visible side-effects like bumping a global counter or doing I/O... It's hard to reason about when that would happen. Or consider even uglier side-effects about exceptions (they're thrown ... when you reference the lazy object?)

Just skip to section 6 in the above paper. (And admire all the type system formal logic on the pages you skip ...)

  • Accepting this answer due to the depth that the paper addresses this feature. Thanks! – Nicole Oct 3 '11 at 18:02
  • TL;DR when you program you have to know what happens to prevent side-effects, with lazyness, this can really get ouf of hand. If you know Hibernate and how much trouble some people have with it, just imagone the same for the whole language. – Walfrat Mar 9 '17 at 8:51
10

Of course it is eminently possible. In fact, scala already has exactly this feature! (Scala is a JVM language and compiles down to bytecode). Here is a piece of scala source:

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

And here is what an intermediate form of the compiled code looks like:

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

}

6

I think you first need to add real properties to the Java langauge, rather than relying on the getX/setX idiom. That way you could just mark the property as lazy (and synchronized, readonly etc...).

Sort of what is asked for here (Objective-C, but concept applies).

0

Of course this could be added to Java, the keyword lazy could be implemented as syntactic sugar. However, wether it will be implemented depends on the vision of the compiler builders.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.