深刻理解Java中final的作用(一):从final的作用剖析String被设计成不可变类的深层原因(二)

2014-11-23 19:28:26 · 作者: · 浏览: 30
ht())+ " Size:"+String.valueOf(appleTag.getSize())); } public static void main(String[]args) { AppleTag appleTag=new AppleTag(300f,10.3f); Apple apple=new Apple(appleTag); apple.print(); appleTag.setWeight(13000f); apple.print(); AppleTag tag=apple.getAppleTag(); tag.setSize(100.3f); apple.print(); } } 程序输出结果如下:

\
显然,尽管此处类的使用者仍然尝试越权去修改appleTag,却没有获得成功,原因就在于:在接收时,在类的内部新建了一个对象并让appleTag指向它;在输出时,使用者获取的是新建的对象,保证了使用者即可以获得相应的值,又无法利用获取的对象来修改appleTag。所以apple始终未被改变,三次输出结果相同。

在我的博客《深刻理解Java中的String、StringBuffer和StringBuilder的区别》一文中已经说过String的对象是不可变的,因而在使用String时即使是直接返回引用也不用担心使用者篡改对象的问题,如下例:

import java.util.*;
class Apple
{
  final String type;
  public Apple(String type)
  {
    this.type=type;
  }
  public String getType()
  {
    return type;
   }
  public void print()
  {
    System.out.println("Type is "+type);
   }
}

public class AppleTest
{
  public static void main(String[]args)
  {
    String appleType=new String("Red Apple");
    Apple apple=new Apple(appleType);
    apple.print();

    appleType="Green Apple";
    apple.print();

    String type=apple.getType();
    type="Yellow Apple";
    apple.print();
  }
}
    
输出结果如下所示:

编程语言,字符串及其处理都占有相当大的比重),显然会给我们日常的程序编写带来极大的不便。

另外一个值得注意的地方就是数组变量名其实也是一个引用,所以final修饰数组时,数组成员依然可以被改变。