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是不会变化的,那假如子类有个名称一样的成员变量会如何呢?代码如下

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的规则,导致了此类不安全。

原文地址:https://www.cnblogs.com/csong7876/p/9125173.html

时间: 2024-11-09 00:34:52

String为什么要设置成Final类型的相关文章

面试题:java中String为什么要设置成final

1.不可改变---执行效率高 2.因为String这个对象基本是被所有的类对象都会使用的到了,如果可以被复写,就会很乱套,比如map的key ,如果是一个string为key的话,String如果可以改变的话,你想想后果 3.执行效率可以这么解释,面向对象有一个多态的性质,如果可以改变,就可以被复写,子类如果复写了某个方法,虚函数表就被用上了:如果是final型的,jvm就直接去用了,根本不用去虚函数表里面找 ----------只要声明成final ,JVM才不用对相关方法在虚函数表中查询,而

在java中string为什么要设计成final的

各种不同的理解 1 将方法或类声明为final主要目的是:确保它们不会再子类中改变语义.String类是final类,这意味着不允许任何人定义String的子类.换言之,如果有一个String的引用,它引用的一定是一个String对象,而不可能是其他类的对象.——<Java核心技术 卷I> 2 举个例子:一个方法可能本来接受String类型并返回其大写方式 public static String uppperString(String s){ return s.toUpperCase();

在java中String类为什么要设计成final?

大神链接:在java中String类为什么要设计成final? - 程序员 - 知乎 我进行了重新排版,并且更换了其中的一个例子,让我们更好理解. String很多实用的特性,比如说"不可变性",是工程师精心设计的艺术品!艺术品易碎!用final就是拒绝继承,防止世界被熊孩子破坏,维护世界和平! 1. 什么是不可变? String不可变很简单,如下图,给一个已有字符串"abcd"第二次赋值成"abcedl",不是在原内存地址上修改数据,而是重新指

为什么jdk中把String类设计成final

为什么jdk中把String类设计成final? 最佳答案: 主要是为了"效率" 和 "安全性" 的缘故.若 String允许被继承, 由于它的高度被使用率, 可能会降低程序的性能,所以String被定义成final. 其它答案一: String和其他基本类型不同,他是个对象类型.既然是对象类型,如果是在静态方法下是必须调用静态方法或值的,如果是非静态的方法,就必须要实例化. main函数是个static的.所以String要能像其他的基本类型一样直接被调用.这也是

Java日期格式化之将String类型的GMT,GST日期转换成Date类型

请尊重他人的劳动成果,转载请注明出处:Java日期格式化之将String类型的GMT,GST日期转换成Date类型 http://blog.csdn.net/fengyuzhengfan/article/details/40164721 在实际开发过程中经常会需要将Date类型的数据封装成XML或Json格式在网络上进行传输,另外在将Date类型的数据存到Sqlite数据库中后再取出来的时候只能获取String类型的日期了,这是因为SQLite是无类型的.这样不得不面对将String 类型的日期

关于springmvc怎么自动把前台string类型日期字段转换成date类型

关于springmvc怎么把前台string类型日期字段转换成date类型字段,小狼想了好久,阅读spring源代码,发现一个很好玩的注解@DateTimeFormat(pattern="yyyy-MM-dd") 对,就是他,小狼是这么使用的 @Controller public class Login { @RequestMapping("/login") public String login(String username,@DateTimeFormat(pa

Swift - 将String类型的数字转换成数字类型(支持十进制、十六进制)

1,十进制的字符串转成数字 Swift中,如果要把字符串转换成数字类型(比如整型,浮点型等).可以先转成NSString类型,让后再转. 1 2 3 4 //将文本框中的值转换成数字 var i = (tf1.text as NSString).intValue var f = (tf1.text as NSString).floatValue var d = (tf1.text as NSString).doubleValue 2,十六进制的字符串转成数字 (1)定义一个转换方法 1 2 3

C#String类型转换成Brush类型

C#String类型转换成Brush类型: using System.Windows.Media; BrushConverter brushConverter = new BrushConverter(); Brush brush = (Brush)brushConverter.ConvertFromString(“#cacaca”); 注意: using System.Windows.Media;时如果出现错误,是因为没有引入PresentationCore 解决方案资源管理器->右击引用->

JavaScript基础 空字符串:string 类型,转成bool类型是 :false Boolean()系统函数

镇场诗: 清心感悟智慧语,不着世间名与利.学水处下纳百川,舍尽贡高我慢意. 学有小成返哺根,愿铸一良心博客.诚心于此写经验,愿见文者得启发.------------------------------------------ code: 1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta http-equiv="Content-Type" content="text/html; charset=ut