这个异步调用在我的例子中是如何工作的

问题描述 投票:0回答:1

我学习Java并想知道这段代码中的item

useResult(result, item);

将被来自的下一个电话覆盖

doItem(item);

这是一个例子:

public void doSomeStuff() {
        //  List with 100 items
        for (Item item : list) {
            doItem(item);
        }
    }

    private void doItem(final Item item) {
        someAsyncCall(item, new SomeCallback() {
            @Override
            public void onSuccess(final Result result) {
                useResult(result, item);
            }
        });
    }

SomeCallback()在未来的某个时间发生,这是另一个线索

我的意思是当回调回归时,useResult(result, item); item是否会相同?

请告知这里发生了什么?

java asynchronous callback
1个回答
1
投票

我的意思是当回调返回时,useResult(result, item);项目是否相同?

当然会,除此之外还有什么效用呢?

你正在做的是创建100个不同的SomeCallback类,它们将处理不同的Item对象。

你的someAsyncCall的骨架可能如下所示:

public static void someAsyncCall(Item i, Callback callback) {
    CompletableFuture.runAsync( () -> { // new thread
        Result result = computeResult(i);
        callback.onSuccess(result, i);
    });
}

关键是:Callback,在实例化的那一刻,他不知道任何关于他将得到的Item作为参数。当Callback::onSuccess将来被执行时,他只会知道它。

那么,Item i会改变(被分配一个新对象)吗?

不,因为它在final中是有效的someAsyncCall(对象值没有明确更改)。

你甚至不能指定i = new Item(),因为编译器会抱怨访问non-final变量的匿名函数。

你当然可以创建一个新的Item并将其传递给回调

Item i2 = new Item();
callback.onSuccess(result, i2);

但那会成为一个令人讨厌的图书馆的地狱......

没有人禁止你做i.setText("bla"),除非你的Result类是immutable(成员字段是final自己)。


编辑

如果您的问题是java如何处理方法参数中的对象,那么答案是:是的,它们只是原始实例的副本。

您可以尝试使用简单的交换方法void swap(Item i1, Item 12);,您会注意到引用只在函数内有效交换,但是一旦返回,对象将分别指向它们的原始实例。

但它是反映原始实例的副本。

回到你的榜样。想象一下,你的someAsyncCall在执行回调之前会等待10000毫秒。

在你的for loop,你打电话给doItem后,你也做:item.setText("bla");

当您在item.getName()中打印useResult时,您将获得bla。即使在调用异步函数后文本已更改。

© www.soinside.com 2019 - 2024. All rights reserved.