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的规则,导致了此类不安全。
String为什么要设置成Final类型的更多相关文章
- 面试题:java中String为什么要设置成final
1.不可改变---执行效率高 2.因为String这个对象基本是被所有的类对象都会使用的到了,如果可以被复写,就会很乱套,比如map的key ,如果是一个string为key的话,String如果可以 ...
- C#后台将string="23.00"转换成int类型
在C# 后台将String类型转换成int 有以下几种方法: (1) int.TryParse(string); (2) Convert.Toint32(string); (3) (int)stri ...
- 025:为什么需要将Logger对象声明为private static final类型的
本文阅读时间大约4分钟. 参考答案 就这个问题而言,我总结了三个原因: 设置为private是为了防止其他类使用当前类的日志对象: 设置为static是为了让每个类中的日志对象只生成一份,日志对象是属 ...
- C# 字符串string类型转换成DateTime类型 或者 string转换成DateTime?(字符串转换成可空日期类型)
在c#中,string类型转换成DateTime类型是经常用到的,作为基本的知识,这里在此做个小结.一般来说可以使用多种方法进行转换,最常用的就是使用Convert.ToDateTime(string ...
- 在java中String类为什么要设计成final?
大神链接:在java中String类为什么要设计成final? - 程序员 - 知乎 我进行了重新排版,并且更换了其中的一个例子,让我们更好理解. String很多实用的特性,比如说“不可变性”,是工 ...
- 【笔记】在java中String类为什么要设计成final?
部分内容转自知乎:https://www.zhihu.com/question/31345592 从自己的理解进行加工,压缩. String本质上是一个final类 public final clas ...
- String和包装类Integer\Double\Long\Float\Character 都是final类型
String和包装类Integer\Double\Long\Float\Character\Boolean 都是final类型 不可以改变
- 在java中String类为什么要设计成final
在java中String类为什么要设计成final? - 胖胖的回答 - 知乎 https://www.zhihu.com/question/31345592/answer/114126087
- String为什么是final类型的
String的源码如下: public final class String implements Serializable, Comparable<String>, CharSequen ...
随机推荐
- Java实现蓝桥杯互补二元组
分三处 1.当差值为0并且只有一个二元组就不管他 2.当差值为0并且二元组个数>=1加上他并减去它本身 3.当差值为存在并且不为0时直接加上他 因为都计算了两次,所以最后ans/2 用了map的 ...
- java实现正六面体染色
** 正六面体染色** 正六面体用4种颜色染色. 共有多少种不同的染色样式? 要考虑六面体可以任意旋转.翻转. 参考答案: 240 Burnside引理,正方体涂色问题 (n^6 + 3*n^4 + ...
- Java实现第八届蓝桥杯青蛙跳杯子
青蛙跳杯子 题目描述 X星球的流行宠物是青蛙,一般有两种颜色:白色和黑色. X星球的居民喜欢把它们放在一排茶杯里,这样可以观察它们跳来跳去. 如下图,有一排杯子,左边的一个是空着的,右边的杯子,每个里 ...
- (四)SQLMap之Tamper篡改脚本的类型、作用、适用场景
目录结构 一.SQLMap中tamper的简介 1.tamper的作用 2.tamper用法 二.适配不同数据库类型的测试tamper 三.SQLMap中tamper篡改脚本的功能解释 一.SQLMa ...
- 彻底搞懂 etcd 系列文章(三):etcd 集群运维部署
0 专辑概述 etcd 是云原生架构中重要的基础组件,由 CNCF 孵化托管.etcd 在微服务和 Kubernates 集群中不仅可以作为服务注册与发现,还可以作为 key-value 存储的中间件 ...
- 第03组 Alpha(2/4)
队名:不等式方程组 组长博客 作业博客 团队项目进度 组员一:张逸杰(组长) 过去两天完成的任务: 文字/口头描述: 制定了初步的项目计划,并开始学习一些推荐.搜索类算法 GitHub签入纪录: 暂无 ...
- hibernate中的映射
hibernate中的映射是指Java类和数据库表中的属性来进行关联,然后通过类来操作数据库中,这就是简单的映射.
- 6、react中的交互
1.ajax 再react中使用ajax和直接使用ajax的用法是完全一样的,只要找好路径即可,但是也有不一样的地方,再react中是通过改变状态state来达到让组件重新渲染的效果,并且放ajax的 ...
- api请求允许跨域的问题
让api请求允许跨域 header("Access-Control-Allow-Origin:*");header('Access-Control-Allow-Credential ...
- IOS 发布 程序截图问题
特别要注意那个有无状态栏时的像素要求 **注意:在截屏模拟器的时候,请把模拟器的Scale设置成100%(Window->Scale->100%) 开模拟器截图,运行每一个iOS型号,然后 ...