String為什麽要設置成Final類型
阿新 • • 發佈:2018-06-02
ide cte uid 只有一個 his void rod tor eat
---今天面試碰到個這樣的問題: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是不會變化的,那假如子類有個名稱一樣的成員變量會如何呢?代碼如下
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的規則,導致了此類不安全。
String為什麽要設置成Final類型