那是多么低效:
List<Object> getList(){
return new LinkedList<Object>();
}
void foo(){
for(Object o: getList()){
do something with o;
}
}
与此相比:
List<Object> getList(){
return new LinkedList<Object>();
}
void foo(){
List<Object> os = getList();
for(Object o: os){
do something with o;
}
}
参考方案
不会有任何明显的差异。
我已经编译了以下代码:
import java.util.LinkedList;
import java.util.List;
public class Test1 {
static List<Object> getList(){
return new LinkedList<Object>();
}
void process(Object o) {}
void foo1(){
for(Object o: getList()){
process(o);
}
}
void foo2(){
List<Object> os = getList();
for(Object o: os){
process(o);
}
}
}
foo1
和foo2
的字节码如下:
void foo1();
Code:
0: invokestatic #26; //Method getList:()Ljava/util/List;
3: invokeinterface #28, 1; //InterfaceMethod java/util/List.iterator:()Ljava/util/Iterator;
8: astore_2
9: goto 24
12: aload_2
13: invokeinterface #34, 1; //InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
18: astore_1
19: aload_0
20: aload_1
21: invokevirtual #40; //Method process:(Ljava/lang/Object;)V
24: aload_2
25: invokeinterface #42, 1; //InterfaceMethod java/util/Iterator.hasNext:()Z
30: ifne 12
33: return
void foo2();
Code:
0: invokestatic #26; //Method getList:()Ljava/util/List;
3: astore_1
4: aload_1
5: invokeinterface #28, 1; //InterfaceMethod java/util/List.iterator:()Ljava/util/Iterator;
10: astore_3
11: goto 26
14: aload_3
15: invokeinterface #34, 1; //InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
20: astore_2
21: aload_0
22: aload_2
23: invokevirtual #40; //Method process:(Ljava/lang/Object;)V
26: aload_3
27: invokeinterface #42, 1; //InterfaceMethod java/util/Iterator.hasNext:()Z
32: ifne 14
35: return
如您所见,两个循环的字节码是相同的。唯一的区别是foo2
在开始时将列表引用存储并加载到局部变量中。
有人可能会争辩说,更好的优化编译器可能可以完全消除os
,从而为两个函数生成相同的代码。
import java.util.Scanner; class newClass { public static void main(String args[]) { Scanner s = new Scanner(System.in); while (s.hasNext()) { System.out.println(s.next()); } s.clos…
Java:线程池如何将线程映射到可运行对象 - java试图绕过Java并发问题,并且很难理解线程池,线程以及它们正在执行的可运行“任务”之间的关系。如果我创建一个有10个线程的线程池,那么我是否必须将相同的任务传递给池中的每个线程,或者池化的线程实际上只是与任务无关的“工人无人机”可用于执行任何任务?无论哪种方式,Executor / ExecutorService如何将正确的任务分配给正确的线程? 参考方案 …
JAVA:字节码和二进制有什么区别? - javajava字节代码(已编译的语言,也称为目标代码)与机器代码(当前计算机的本机代码)之间有什么区别?我读过一些书,他们将字节码称为二进制指令,但我不知道为什么。 参考方案 字节码是独立于平台的,在Windows中运行的编译器编译的字节码仍将在linux / unix / mac中运行。机器代码是特定于平台的,如果在Windows x86中编译,则它将仅在Win…
java:继承 - java有哪些替代继承的方法? java大神给出的解决方案 有效的Java:偏重于继承而不是继承。 (这实际上也来自“四人帮”)。他提出的理由是,如果扩展类未明确设计为继承,则继承会引起很多不正常的副作用。例如,对super.someMethod()的任何调用都可以引导您通过未知代码的意外路径。取而代之的是,持有对本来应该扩展的类的引用,然后委托给它。这是与Eric…
Java:BigInteger,如何通过OutputStream编写它 - java我想将BigInteger写入文件。做这个的最好方式是什么。当然,我想从输入流中读取(使用程序,而不是人工)。我必须使用ObjectOutputStream还是有更好的方法?目的是使用尽可能少的字节。谢谢马丁 参考方案 Java序列化(ObjectOutputStream / ObjectInputStream)是将对象序列化为八位字节序列的一种通用方法。但…