当前位置: 代码迷 >> J2SE >> java final 润色 对象
  详细解决方案

java final 润色 对象

热度:569   发布时间:2016-04-23 19:54:47.0
java final 修饰 对象

package demo;

import java.util.LinkedList;

public class DemoQueue {
Demo demo = null;
public static void main(String[] args) {
System.out.println("开始main");
new DemoQueue().aa();
System.out.println("结束main");
}

public void aa(){
System.out.println("进入aa()");
final Print print = new Print();
for(int i = 0 ;i<10;i++){
demo = new Demo(i+"aa");
System.out.println("进入for");
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("进入run"+demo);
print.p(demo);
}
}).start();
}
}
}

class Demo {
private String name;
public Demo(){

}
public Demo(String _name){
this.name = _name;
}
public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}


}
class Print{
public void p(Demo demo){
System.out.println(demo.getName());
}
}

结果

开始main
进入aa()
进入for
进入for
进入for
进入rundemo.Demo@5d888759
2aa
进入rundemo.Demo@3ce53108
3aa
进入for
进入rundemo.Demo@6af62373
3aa
进入for
进入rundemo.Demo@55f33675
4aa
进入for
进入for
进入rundemo.Demo@525483cd
7aa
进入rundemo.Demo@2f9ee1ac
7aa
进入rundemo.Demo@525483cd
7aa
进入for
进入for
进入rundemo.Demo@133c5982
9aa
进入for
进入rundemo.Demo@5f186fab
9aa
结束main
进入rundemo.Demo@5f186fab
9aa



若将demo = new Demo(i+"aa"); 这行代码修改为 final Demo demo = new Demo(i+"aa");时 demo对象的地址都是不一样的

final修饰的对象 。对象的地址是不能改变的,但是对象的属性值是可以改变的。
问题:在for中new 完了对象之后。可能还没有进入run方法就进入下一个循环了。这时候再new的时候 虽说有final 但是这是一个新的对象了。再进入run的时候 不会把上一个对象替换掉么。?因为final的原因么。?

个人想法:每次创建一个线程时,因为有final 的修饰这个线程操作的对象地址是不变的 所以这个线程操作的对象还是当初传入的那个,若没有final 线程在run的时候因为对象的地址改变了所以就是另一个对象 了。不知道 可不可以这么理解 。。可能是我钻牛角尖了。 
这跟线程有点关系.?

------解决思路----------------------
首先呢,如果你将demo = new Demo(i+"aa"); 这行代码修改为 final Demo demo = new Demo(i+"aa");,
那么这个for里面的demo已经是个新变量了,它已经把DemoQueue的demo遮蔽了。

然后呢,每次进for循环,都会有全新的demo,相应run方法访问的也是当次循环对应的demo。

因此你说的“上个线程访问当本次demo”是不可能的。

实际上匿名内部类在实例化时会获得一份demo引用的拷贝,不会与上次交叉的。可以理解成闭包。
  相关解决方案