Pay Attention to the Reference of Java

   
     今天调试了个这样的一个问题,在Java中很容易就会忽略了引用的问题,一不小心就被会这实质为指针的引用给隐藏了臭虫,若没调试我就中了这招。

我用以下的例子来展现这样的问题:
我们定义两个类:Drawer和Apple
/**
 * Object Apple
 */
public class Apple {
	private String color;

	public String getColor() {
		return color;
	}

	public void setColor(String color) {
		this.color = color;
	}
}
 
/**
 * Object Drawer that is used to put apples.
 * Actually, it is used to put appleBox which is used to put apples.
 */
public class Drawer {
	private List<Apple> appleBox;

	public Drawer() {
		appleBox=new ArrayList<Apple>();
	}

	public Drawer(List<Apple> appleBox) {
		this.appleBox = appleBox;
	}
	
	public void putAppleToBox(Apple apple){
		this.appleBox.add(apple);
	}
	
	public void setAppleBox(List<Apple> appleBox) {
		this.appleBox = appleBox;
	}

	public List<Apple> getAppleBox(){
		return appleBox;
	}
}
      Our test case is :
    public void testDrawer(){		
		Drawer drawer=new Drawer();
		Apple apple=new Apple();
		apple.setColor("Red");
		drawer.putAppleToBox(apple);
		System.out.println(drawer.getAppleBox().get(0).getColor());
		System.out.println("---------");
		
		Drawer drawer2=new Drawer();
		drawer2.setAppleBox(drawer.getAppleBox());//关键所在	
		Apple apple2=new Apple();
		apple2.setColor("Yellow");
		drawer2.putAppleToBox(apple2);
		System.out.println(drawer.getAppleBox().size());
		System.out.println(drawer2.getAppleBox().size());
		System.out.println("---------");
		drawer2.getAppleBox().get(0).setColor("Green");
		System.out.println(drawer.getAppleBox().get(0).getColor());
		System.out.println(drawer.getAppleBox().get(1).getColor());
		System.out.println(drawer2.getAppleBox().get(0).getColor());
		System.out.println(drawer2.getAppleBox().get(1).getColor());		
	}
  The test result will be:
Red
---------
2
2
---------
Green
Yellow
Green
Yellow
    
       经验丰富的程序员可能一眼就看出来这样一个实质问题:这里的AppleBox的ArrayList实例只有一个。两个抽屉里面的appleBox引用指向的是同一个ArrayList实例。
这里有个误区,就是以为new了两个抽屉的实例就以为万事大吉了。
当使用drawer2.setAppleBox(drawer.getAppleBox());时,只是将drawer2的appleBox引用指向drawer的appleBox指向的实例。

我们再简化上面的程序:
Apple不变,讲抽屉简化只能放一个苹果,去掉AppleBox这个类:
/**
 * Object Drawer that is used to put one apple.
 */
public class Drawer {
	private Apple apple;

	public Drawer() {		
	}

	public void putApple(Apple apple){
		this.apple=apple;
	}
	
	public Apple getApple(){
		return apple;
	}
}
   Our Test case :
    public void testDrawer(){
		Drawer drawer=new Drawer();
		Apple apple=new Apple();
		apple.setColor("Red");
		drawer.putApple(apple);
		System.out.println(drawer.getApple().getColor());
		
		Drawer drawer2=new Drawer();
		drawer2.putApple(drawer.getApple());
		drawer2.getApple().setColor("Green");
		System.out.println(drawer.getApple().getColor());
		System.out.println(drawer2.getApple().getColor());			
    }
  The test result will be:
Red
Green
Green
其实实质是一样的,这里的Apple实例只有一个,两个抽屉的apple引用指向同一个Apple实例。

总结:
1. Java中的Reference实质就是指针;
2. 使用他,你得特别地注意了。
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值