String为什么要设置成Final类型

---今天面试碰到个这样的问题:String在设计的时候为什么要设计成final的  当时回答的是String功能已经很丰富了,不需要对其进行扩展,所有巴拉巴拉。

现在来正确看看为什么定义成final的吧

首先,Final来修饰一个类,只有一个作用,就是不让此类被继承。

好,那么String为什么不让其他类继承呢,网上看来看去,最靠谱的说法就是保证安全性,(其实也就是因为String的不可变性。)

先看String内部结构:

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence { /** The value is used for character storage. */ private final char value[];   /** The offset is the first index of the storage that is used. */ private final int offset;   /** The count is the number of characters in the String. */ private final int count;   /** Cache the hash code for the string */ private int hash; // Default to 0   /** use serialVersionUID from JDK 1.0.2 for interoperability */ private static final long serialVersionUID = -6849794470754667710L;   。。。。。。。。。。。。。。。。。。

String里有个成员变量value字符型数组。修饰是private ,final

private保证变量不会被外部和子类直接访问。

final保证变量的值不会变化。

但是这样是没办法保证value不可变,因为value是指向数组的地址,我们可以通过修改数组内容从而达到修改value的目的。

也就是这个原因,String内的value就成了一个不可变的值,所以String不可变的原因就在这里。假如String去掉Final,会导致value变化吗,这问题 ,事实证明,父类的value是不会变化的,那假如子类有个名称一样的成员变量会如何呢?代码如下

扫描二维码关注公众号,回复: 1399378 查看本文章
package com.zxy.test;

import java.awt.*;
 /**  * Created by Roderick on 2017/5/12.  */ public class Test2 { /**  * 父类要设计成安全的模式 */ static class Base{ private final char[] value = {'a'};  public String getString(){ return this.toString();  } public void setString(String str){ System.out.println("数组不能被修改");  } public String toString(){ StringBuilder tmp = new StringBuilder();  for(char c: this.value){ tmp.append(c);  } return tmp.toString();  } } static class Child extends Base{ public char[] value;  @Override  public String getString(){ return this.toString();  } @Override  public void setString(String str){ this.value = str.toCharArray();  } @Override  public String toString(){ StringBuilder tmp = new StringBuilder();  for(char c: this.value){ tmp.append(c);  } return tmp.toString();  } } public static void main(String[] arge){ Base base = new Base();  base.setString("aaaa");  System.out.println(base.getString());   Child child = new Child();  child.setString("aaaa");  System.out.println(child.getString());  } } 

上面的代码,已经回答了这个答案,假如子类有个成员变量的名称和value一致,那么value从效果上看,就是被修改了。所以这就导致了子类可变。违背了String的规则,导致了此类不安全。

猜你喜欢

转载自www.cnblogs.com/csong7876/p/9125173.html