String为什么要设置成Final类型-自我总结

来源:互联网 发布:数据迁移解决方案 编辑:程序博客网 时间:2024/06/03 21:58

首先,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的目的。

看了知乎的一个解释(https://www.zhihu.com/question/31345592)


也就是这个原因,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的规则,导致了此类不安全。

1 0
原创粉丝点击