我学习Java并想知道这段代码中是否item
:
useResult(result, item);
将来自
的下一个电话会覆盖doItem(item);
这是eaxmple:
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
是否相同?
请告知这里发生了什么?
答案 0 :(得分: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
。即使在调用异步函数后文本已更改。