.......
{
private BufferedReader br = new BufferedReader(...); new testThread(br).start;
}
.......有个问题请教一下,程序执行到了}后,对象变量br的生存期就结束了,为什么testThread可以继续使用br呢?
传对象本质应该是传地址,生存期结束后,br的占用的内存空间是无效了,但是testThread却可以一直使用br,看起来是一直有效的,为什么会这样,请各位高手指教,多谢。
{
private BufferedReader br = new BufferedReader(...); new testThread(br).start;
}
.......有个问题请教一下,程序执行到了}后,对象变量br的生存期就结束了,为什么testThread可以继续使用br呢?
传对象本质应该是传地址,生存期结束后,br的占用的内存空间是无效了,但是testThread却可以一直使用br,看起来是一直有效的,为什么会这样,请各位高手指教,多谢。
因此在br生存期结束后,使用的是在构造方法中声明的形参,而不是原来的br。
而存在于堆区的对象地址应该是一直存在的,
而Thread中是新的对象声明指向了这个地址。
关键要理解private BufferedReader br = new BufferedReader(...);包含的内容!
首先,在在栈区创建了一个br引用,然后,打开操作栈,将操作数的引用放进来,此时,br变成了指向了被开辟数的一个引用!【PS:可能会觉得为什么br不是在堆区,因为声明的缘故,c++里面,称作为正所谓“引用于栈”,你可以整么理解】
所以,当把br作为参数传入tesThread时,传的并非原本声明的那个br 。
我举个简单例子你看下:
//例子
import java.io.*;
public class testThread{
public testThread(BufferedReader br){}
public void start(){}
}
//测试例
import java.io.*;
public class Test {
public static void main(String[]args){
try{
BufferedReader br = new BufferedReader(
new InputStreamReader(
new FileInputStream(
"E://Test.java"
)
));
new testThread(br).start();
}catch(Exception err){/**举例子,撒也不做*/}
}
}
--------------------------
我们来看看Java的class文件里面的编译:
public class Test extends java.lang.Object{
public Test();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: returnpublic static void main(java.lang.String[]);
Code:
0: new #2; //class java/io/BufferedReader
3: dup
4: new #3; //class java/io/InputStreamReader
7: dup
8: new #4; //class java/io/FileInputStream
11: dup
12: ldc #5; //String E://Test.java
14: invokespecial #6; //Method java/io/FileInputStream."<init>":(Ljava/lan
g/String;)V
17: invokespecial #7; //Method java/io/InputStreamReader."<init>":(Ljava/i
o/InputStream;)V
20: invokespecial #8; //Method java/io/BufferedReader."<init>":(Ljava/io/R
eader;)V
23: astore_1
24: new #9; //class testThread
27: dup
28: aload_1
29: invokespecial #10; //Method testThread."<init>":(Ljava/io/BufferedRead
er;)V
32: invokevirtual #11; //Method testThread.start:()V
35: goto 39
38: astore_1
39: return
Exception table:
from to target type
0 35 38 Class java/lang/Exception
}
-------------------------------
看不懂?不要紧,我就把最关键的一句拿给你看:
28: aload_1
29: invokespecial #10; //Method testThread."<init>":(Ljava/io/BufferedRead
er;)V
32: invokevirtual #11; //Method testThread.start:()V
28:将一个引用类型变量至于栈顶
29:初始化构造函数(类testThread被构造了)
30:启动start方法。
------------------
联合28、29、30这3句可知,被传入的,可不是一个普通变量,而是引用了某个具体地址空间的引用类型!所以,不必担心"}"了,br消失了,就不能运行了----------------------------------------------------
这是我的理解!高手请指教!勿喷!