---今天面试碰到个这样的问题: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类型的更多相关文章

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

    1.不可改变---执行效率高 2.因为String这个对象基本是被所有的类对象都会使用的到了,如果可以被复写,就会很乱套,比如map的key ,如果是一个string为key的话,String如果可以 ...

  2. C#后台将string="23.00"转换成int类型

    在C# 后台将String类型转换成int 有以下几种方法: (1)  int.TryParse(string); (2) Convert.Toint32(string); (3) (int)stri ...

  3. 025:为什么需要将Logger对象声明为private static final类型的

    本文阅读时间大约4分钟. 参考答案 就这个问题而言,我总结了三个原因: 设置为private是为了防止其他类使用当前类的日志对象: 设置为static是为了让每个类中的日志对象只生成一份,日志对象是属 ...

  4. C# 字符串string类型转换成DateTime类型 或者 string转换成DateTime?(字符串转换成可空日期类型)

    在c#中,string类型转换成DateTime类型是经常用到的,作为基本的知识,这里在此做个小结.一般来说可以使用多种方法进行转换,最常用的就是使用Convert.ToDateTime(string ...

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

    大神链接:在java中String类为什么要设计成final? - 程序员 - 知乎 我进行了重新排版,并且更换了其中的一个例子,让我们更好理解. String很多实用的特性,比如说“不可变性”,是工 ...

  6. 【笔记】在java中String类为什么要设计成final?

    部分内容转自知乎:https://www.zhihu.com/question/31345592 从自己的理解进行加工,压缩. String本质上是一个final类 public final clas ...

  7. String和包装类Integer\Double\Long\Float\Character 都是final类型

    String和包装类Integer\Double\Long\Float\Character\Boolean 都是final类型 不可以改变

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

    在java中String类为什么要设计成final? - 胖胖的回答 - 知乎 https://www.zhihu.com/question/31345592/answer/114126087

  9. String为什么是final类型的

    String的源码如下: public final class String implements Serializable, Comparable<String>, CharSequen ...

随机推荐

  1. PAT 挖掘机技术哪家强

    为了用事实说明挖掘机技术到底哪家强,PAT 组织了一场挖掘机技能大赛.现请你根据比赛结果统计出技术最强的那个学校. 输入格式: 输入在第 1 行给出不超过 105 的正整数 N,即参赛人数.随后 N  ...

  2. 6.keras-基于CNN网络的Mnist数据集分类

    keras-基于CNN网络的Mnist数据集分类 1.数据的载入和预处理 import numpy as np from keras.datasets import mnist from keras. ...

  3. js排他性算法

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  4. 定时器+echarts运行时间太长导致内存溢出页面崩溃

    最近做的项目需要在页面上展示echarts图表,且数据每隔10s刷新一次,然后发现时间长了以后chorme浏览器会显示页面崩溃.一开始以为是定时器的原因,试了网上的很多方法,比如把setInterva ...

  5. webstorm 快捷键 失效问题

    解决方案一:  file->Settings->Keymap->设置为Default 解决方案二:  file->Settings->IdeaVim->取消对勾 重 ...

  6. virtualbox 基于nat模式搭建局域网并且和宿主机通信

    1.VIRTUALbox 2.两台虚拟机,设置网络为DHCP方式 检查文件确认是dhcp模式不是的百度搜索修改:/etc/sysconfig/network-scripts/ifcfg-enps3(网 ...

  7. 读Linux高性能服务器编程-12章http服务器源码

    title:用线程池实现的http服务器 从main函数看起 解析ip地址(点分制, 端口号) 设置忽略SIGPIPE信号 初始化线程池,池中创建了8个线程,每个线程对应一个work函数 初始化htt ...

  8. 10.实战交付一套dubbo微服务到k8s集群(3)之二进制安装Maven

    maven官网:https://maven.apache.org/ maven二进制下载连接:https://archive.apache.org/dist/maven/maven-3/3.6.1/b ...

  9. c++构造函数的调用方法

    #include<iostream> using namespace std; class Base { public: Base(){ cout<<"hello&q ...

  10. Kali中密码暴力破解工具hydra的使用

    前言 hydra是著名黑客组织thc的一款开源的暴力破解密码工具,功能非常强大,kali下是默认安装的,几乎支持所有协议的在线破解.密码能否破解,在于字典是否强大.本文仅从安全角度去讲解工具的使用,请 ...