在无限循环中使用匿名与嵌套 class (Java)
Using anonymous vs nested class in an infinite loop (Java)
在无限循环的上下文中哪个更好:匿名 class 还是嵌套 class?
如我所见,如果我们使用匿名 class,它会在每次迭代时重新定义,但使用嵌套 class,我们仍然会创建一个实例,但 class 本身不会重新定义。不确定这是否正确...在这种情况下使用一个与另一个相比有什么优势吗?
public class MainThread {
public static void main(String[] args){
while (true) {
final int data = rand.nextInt();
//Runnable task = new MyRunnable(data);
Runnable task = new Runnable() {
public void run() {
printData(data);
}
};
new Thread(task).start();
}
}
private static class MyRunnable implements Runnable {
private int data;
MyRunnable(int data){
this.data = data;
}
@Override
public void run() {
printData(data);
}
}
}
匿名内部 class 不是 "redefined for each call" - 它们应该与内部 class 具有完全相同的开销,除了您的内部 class 是静态的因此避免保留对外部 this
的引用,如果有的话。
如果你编译上面的程序,你会看到生成了几个classes:
MainThread.class
MainThread.class
MainThread$MyRunnable.class
反编译 $1(=你的内部匿名 class)和 $MyRunnable(=你的内部命名 class)表明它们本质上是相同的:
MainThread(int);
Code:
0: aload_0
1: iload_1
2: putfield #1 // Field val$data:I
5: aload_0
6: invokespecial #2 // Method java/lang/Object."<init>":()V
9: return
public void run();
Code:
0: aload_0
1: getfield #1 // Field val$data:I
4: invokestatic #3 // Method MainThread.printData:(I)V
7: return
和
class MainThread$MyRunnable implements java.lang.Runnable {
MainThread$MyRunnable(int);
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: aload_0
5: iload_1
6: putfield #2 // Field data:I
9: return
public void run();
Code:
0: aload_0
1: getfield #2 // Field data:I
4: invokestatic #3 // Method MainThread.printData:(I)V
7: return
}
唯一的区别是匿名内部 class 没有在其构造函数中存储 'data',而是从外部静态最终变量中读取它。
在无限循环的上下文中哪个更好:匿名 class 还是嵌套 class? 如我所见,如果我们使用匿名 class,它会在每次迭代时重新定义,但使用嵌套 class,我们仍然会创建一个实例,但 class 本身不会重新定义。不确定这是否正确...在这种情况下使用一个与另一个相比有什么优势吗?
public class MainThread {
public static void main(String[] args){
while (true) {
final int data = rand.nextInt();
//Runnable task = new MyRunnable(data);
Runnable task = new Runnable() {
public void run() {
printData(data);
}
};
new Thread(task).start();
}
}
private static class MyRunnable implements Runnable {
private int data;
MyRunnable(int data){
this.data = data;
}
@Override
public void run() {
printData(data);
}
}
}
匿名内部 class 不是 "redefined for each call" - 它们应该与内部 class 具有完全相同的开销,除了您的内部 class 是静态的因此避免保留对外部 this
的引用,如果有的话。
如果你编译上面的程序,你会看到生成了几个classes:
MainThread.class
MainThread.class
MainThread$MyRunnable.class
反编译 $1(=你的内部匿名 class)和 $MyRunnable(=你的内部命名 class)表明它们本质上是相同的:
MainThread(int);
Code:
0: aload_0
1: iload_1
2: putfield #1 // Field val$data:I
5: aload_0
6: invokespecial #2 // Method java/lang/Object."<init>":()V
9: return
public void run();
Code:
0: aload_0
1: getfield #1 // Field val$data:I
4: invokestatic #3 // Method MainThread.printData:(I)V
7: return
和
class MainThread$MyRunnable implements java.lang.Runnable {
MainThread$MyRunnable(int);
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: aload_0
5: iload_1
6: putfield #2 // Field data:I
9: return
public void run();
Code:
0: aload_0
1: getfield #2 // Field data:I
4: invokestatic #3 // Method MainThread.printData:(I)V
7: return
}
唯一的区别是匿名内部 class 没有在其构造函数中存储 'data',而是从外部静态最终变量中读取它。