我学习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
是否会相同?
请告知这里发生了什么?
我的意思是当回调返回时,
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
。即使在调用异步函数后文本已更改。