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. 使用他,你得特别地注意了。
 
发布了59 篇原创文章 · 获赞 5 · 访问量 13万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览