Kotlin代表未来

我正在努力学习科特林,代表们既有趣又令人困惑。 我有一个情况,在一个java类中,我将构造函数arg创建一个Future(ID表示另一个系统中的资源),并将Future作为一个实例变量存储。 那么“getXXX”会调用Future.get()

这里是一个示例java类

 public class Example { private Future<Foo> foo; public Example(String fooId) { this.foo = supplyAsync(() -> httpClient.get(fooId)); } public Foo getFoo() { return foo.get(); } } 

我不提供Kotlin的例子,因为我不知道如何构建它。

您可以使用自定义属性获取器以简单的方式将Java代码转换为Kotlin:

 class Example(fooId: Int) { private val fooFuture = supplyAsync { httpClient.get(fooId) } val foo: Foo get() = fooFuture.get() } 

但Kotlin有一个更强大的概念来概括财产行为 – 财产代表 :

 class Example { val foo: Foo by someDelegate } 

在这个例子中, someDelegate是一个定义属性foo行为的对象。

尽管Future<V>不能用作Kotlin中的代理,但是可以通过实现getValue(thisRef, property)和(对于可变属性) setValue(thisRef, property, value)函数来创建自己的属性委托当读取一个属性(和写入,如果可变的话)时明确提供要执行的代码。

这些函数可以是您的项目类的成员函数或扩展函数 ,符合Future<V> 。 基本上,要使用Future<V>作为属性委托,您必须为其定义getValue(thisRef, value)扩展函数,例如:

 operator fun <V> Future<V>.getValue(thisRef: Any?, property: KProperty<*>) = get() 

在这里,代理将为一个属性提供的值将被简单地从Future::get调用中取出,但是一个适当的实现可能应该处理取消和异常处理。 为了这个目的,你可以把Future<V>包装成一个类,它也定义了后备值/策略,然后使用这个类中的objects。

然后,您可以使用Future<V>对象作为您的属性的代表:

 class Example(fooId: Int) { val foo: Foo by supplyAsync { Thread.sleep(2000); fooId } } fun main(args: Array<String>) { val e = Example(123) println(e.foo) }