有什么理由不能将延迟初始化内置到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
不知道,但是示例代码不是线程安全的
Armand

2
@Alison synchronized关键字的工作原理与该方法相同。我想将会有一些更复杂的构造方法。在我的特定用例中,由于问题的性质,对于每个请求而言,同步都是没有意义的。
妮可

在C#中,Lazy在库中,但该语言支持。sankarsan.wordpress.com/2009/10/04/laziness-in-c-4-0-lazyt Java是否具有lambda,委托和闭包?顺便说一句,您确实想在SO上提出这个问题,以便Jon Skeet&co。可以分享他们的智慧。
工作

3
您几乎可以将所有内容构建为任何语言。但是复杂性预算和功能列表是有限的,语言设计者只能包含他们认为最重要的内容(当然,除了Larry Wall之外-特别是在Perl 6中,也就是“您的所有范例都属于我们”)。

1
根本问题是Java是唯一没有元编程功能的静态类型语言。在C语言中,您可以在十分钟内将其编写为宏。在C ++中,您可以在大约两分钟内将其编写为模板。在Java中,您可以...粘贴和修改。
凯文·克莱恩

Answers:


14

这是您问题的八页答案:http : //tinlizzie.org/~awarth/papers/fool07.pdf

如果我可以尝试粗略地总结一下添加懒惰的问题,那就是极端的情况。关于副作用有很多警告。在您的示例中,请考虑一下,如果构造函数有明显的副作用,例如撞到全局计数器或执行I / O ...很难推断何时会发生这种情况。还是考虑关于异常的更丑陋的副作用(当您引用惰性对象时,它们会被抛出……)

只需跳到以上论文的第6节。(并欣赏您跳过的页面上的所有类型系统形式逻辑……)


由于本文着重介绍此功能,因此请接受此答案。谢谢!
妮可,

TL; DR在编写程序时,您必须了解会发生什么情况以防止产生副作用,而且很懒惰,这确实可以帮上忙。如果您了解Hibernate以及某些人遇到的麻烦,只需对整个语言使用相同的语言即可。
Walfrat

10

当然,这是绝对可能的。实际上,scala已经完全具有此功能!(Scala是一种JVM语言,可编译为字节码)。这是一个scala源代码:

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 2014年

6

我认为您首先需要向Java语言添加真实属性,而不是依赖于getX / setX习惯用法。这样,您可以将属性标记为惰性(以及同步,只读等)。

这里需要什么(Objective-C,但概念适用)。


0

当然,这可以添加到Java中,关键字lazy可以实现为语法糖。但是,能否实现取决于编译器构建者的愿景。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.