1. 程式人生 > >String為什麽要設置成Final類型

String為什麽要設置成Final類型

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類型