java有string这个类型吗_关于java的String类型

String类型的不可变

众所周知,String类型是不可变的,一旦String对象被创建好了则这个字符串中的序列就不可改变。

为什么String类型是不可变?

根据阅读源码可知,String类是一个final类,但是String不可变并不是因为它是一个final类,final修饰的类只是不能被继承,因为有字符串常量池这个东西,如果String类能被继承就会出现安全问题。关于String不可变的原因是因为下面这句代码:

private final char value[];

value负责存储String的值,因为value是用final修饰的,所以value的地址不能被改变(但是数组的值可以被改变),又因为在String类中并没有任何方法能够修改value的元素,所以String是不可变的。但是在有的时候我们认为字符串改变了啊,例如String s="hi"; s+=" world";s输出就会变成"hi world",这是因为重新给了s一个字符串对象,相加后的对象和以前的对象不一样,后面将会有代码演示。

String类型真的不可变吗?

因为value是一个char数组,他只是地址不可变,其中的值是可变的,String不可变是因为它没有提供给我们可以修改value的方法,但是我们可以通过反射获取到value数组,然后修改它的值,这样可以实现“String的可变”。如下代码所示:

String s1= "hello world";

String s2 ="hello world";

System.out.println(s1==s2);

System.out.println(s1);

System.out.println(s2);

Field field = String.class.getDeclaredField("value");

field.setAccessible(true);

char[] value = (char[])field.get(s1);

value[1]='i';

value[2]='i';

value[3]='i';

value[4]='i';

System.out.println(s1==s2);

System.out.println(s1);

System.out.println(s2);

输出结果

true

hello world

hello world

true

hiiii world

hiiii world

通过上面可以看出当我们改变s1的值时s2被改变了。

关于String的一些常识

如下代码

String s1 = "hello world";

String s2 = "hello world";

String s3 = "hello "+"world";

String s4 = new String("hello world");

String s5 = "hello" + new String("world");

String s6 = new String("hello ");

String s7="world";

String s8 ="hello ";

String s9=s6+s7;

String s10=s8+s7;

System.out.println(s1==s2);

System.out.println(s1==s3);

System.out.println(s1==s4);

System.out.println(s1==s5);

System.out.println(s4==s5);

System.out.println(s1==s9);

System.out.println(s1==s10);

System.out.println(s9==s10);

s1 = s1+"!";

System.out.println(s1);

System.out.println(s2);

System.out.println(s1==s2);

输出结果

true

true

false

false

false

false

false

false

hello world!

hello world

false

在String中使用new就新创建一个对象,不论字符串常量池是否有它,而s3和s10的区别在于,在编译阶段就能确定s3,因为s3指定了是"hello "和"world"相结合,而s10在编译阶段程序并不能确定s8和s7的值。

String一些方法可能产生新的对象

subString

当subString截取的字符串就是本身的时候,返回本身,否则返回一个新声明的字符串。

replace

如果新字符和要替换的一样的话,返回本身,否则返回一个新声明的字符串。

toCharArray

返回一个新的字符数组,对改数组进行修改不会对String产生任何影响。

toString

返回的是字符串本身

trim

trim方法是返回String对象的一个副本,该副本去除了原来字符串中的首部和尾部空白。但如果String对象首部和尾部没有空白的话,则返回自身。否则调用subString方法返回一个崭新的String对象(真子串,subString方法中说过)。

关于String传参

在开始String传参的时候先看看参数传递的两大类型:

值传递:在我们进行参数传递的时候将实参拷贝一份传递过去,所以在方法里面对其更改不会对原本的造成影响。

引用传递:在java中引用传递是拷贝该对象的地址传递过去,如果在传递过去的地址对应的对象上进行修改就会影响原本的值。

具体例子如下:

//自己声明的一个类

class Ref {

private String name;

public void setName(String name) {

this.name = name;

}

public String getName(){

return name;

}

@Override

public String toString() {

return "Ref{" +

"name='" + name + '\'' +

'}';

}

}

public static void main(String[] args) {

Ref ref = new Ref();

ref.setName("张三");

int a=5;

String name = "张三";

change(ref);

change(a);

change(name);

System.out.println(ref);

System.out.println(a);

System.out.println(name);

}

public static void change(Ref ref) {

ref.setName("李四");

}

public static void change(int num) {

num = 18;

}

public static void change(String name) {

name = "李四";

}

//上面输出

/*

Ref{name='李四'}

5

张三

*/

//将ref 的change函数改变如下

public static void change(Ref ref) {

Ref ref1 = new Ref();

ref = ref1;

ref.setName("李四");

}

/*运行

Ref{name='张三'}

5

张三

*/

通过上面的例子我们发现对象的传递如果在方法里面进行了修改将会改变原本的值。但是!!!要注意我们传递过去的只是地址,如下图所示,我们进行传递的时候将ref对象的地址拷贝一份传递过去(注意是拷贝一份),当我们没有对传递过去的形参地址进行修改的情况下,对该形参进行修改都会影响原本的实参,例如上面前面的change方法,如果进行对形参的地址进行修改了的话将会和原本的实参断绝关系,例如上面修改后的change方法。而上面的String的change就不用说了 name= "李四"相当于将name的地址修改为了字符串常量池中的"李四"对象。

9d5266533ab3

ref的存储结构.png

通过上面的我们明白了什么是引用传递和值传递。关于String传参可能大家也有了答案。

String传参的时候传递String对象所指向的地址,但是由于String中没有方法能够对value数组进行修改,所以我们在对String参数进行操作的时候都不会改变他的值,很多情况下我们认为String的值变化了都是一种错觉。比如下面的replace方法

public static void change(String name) {

name.replace('张','李');

}

上面的代码很容易让我们产生name中的"张"换成了"李"的错觉,但是其实并没有改变,我们可以看一看replace的具体是怎么实现的

9d5266533ab3

replace.png

我们可以看出repalce中并没有对原本value数组进行更改,而是将value中的数组拷贝到buf中(需要替换的替换),然后返回一个new String。具体其他你认为String内容改变了的地方你可以阅读源码进行观察,你就会发现其实都没有更改。

关于String的其他内容可以点击查看

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/520995.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

理论与实践:如何从Hadoop迁移到MaxCompute

直播视频回看,传送门!分享资料下载,传送门!更多精彩内容传送门:大数据计算技术共享计划 — MaxCompute技术公开课第二季 以下内容根据演讲视频以及PPT整理而成。 通常而言,将Hadoop迁移到MaxCompute会分为…

rocketmq原理_彻底看懂RocketMQ事务实现原理

面试中经常会问到比如RocketMQ的事务是如何实现的呢?学习框架,我们不仅要熟练使用,更要掌握设计及原理,才算熟悉一个框架。1 RocketMQ 事务使用案例public class CreateOrderService { Autowired private OrderDao orderDao; A…

要活 102 年,阿里凭借的是什么?

戳蓝字“CSDN云计算”关注我们哦!作者 | 屠敏责编 | 阿秃由浅到深、由轻到重、由拥抱到创新,看似“风平浪静”的历史背后,中国互联网江湖的发展实则“波涛汹涌”。对于身处核心位置的科技巨头阿里巴巴而言,将如何更好地去实现“希…

阿里云 x 蒙牛 | 打通数据孤岛,基于MaxCompute实现产销协同的智慧运营

每一个公司转型的背后 都有着不为人知的秘密 今天,让我们一起探秘 内蒙古蒙牛乳业(集团)股份有限公司是中国发展速度最快的乳品企业之一,2017年实现收入601.56亿元,位列全球乳业第10位,与2016年同比收入增…

(Docker实战) 第3篇:Centos7 拉取和部署Mysql

文章目录搭建mysql1. 创建mysql的配置文件2. 创建mysql配置/srv/mysql/conf/custom.cnf3. 下载并安装mysql 5.7(注意修改密码)搭建mysql 1. 创建mysql的配置文件 mkdir -p /srv/mysql/conf /srv/mysql/logs /srv/mysql/data2. 创建mysql配置/srv/mysql…

Hadoop迁移MaxCompute神器之DataX-On-Hadoop使用指南

DataX-On-Hadoop即使用hadoop的任务调度器,将DataX task(Reader->Channel->Writer)调度到hadoop执行集群上执行。这样用户的hadoop数据可以通过MR任务批量上传到MaxCompute、RDS等,不需要用户提前安装和部署DataX软件包,也不需要另外为…

(Docker实战) 第三篇:配置_开发环境

文章目录一、开发环境-建立开发环境1.1. 常用环境下载地址1.2. IDEA的maven配置1.3. 导入项目示例1.4. IDEA教程,如何从eclipse过渡1.5. gblfy的快捷键风格一、开发环境-建立开发环境 1.1. 常用环境下载地址 jdk8下载地址: https://www.oracle.com/te…

阿里云史上最大技术升级:面向万物智能的飞天2.0

1991年,《科学美国人》杂志描绘了一种“无处不在的计算设备,没人会感觉到它的存在”,拉开了万物智能的序幕。 27年后的2018杭州•云栖大会上,阿里云公布了面向万物智能的新一代云计算操作系统——飞天2.0,可满足百亿级…

杭州·云栖大会宣布多款核心云产品降价,最高降幅达90%

2018杭州云栖大会,阿里云宣布开启新一轮核心产品降价,再次用科技普惠广大开发者和用户,加速产业升级。本次降价涉及近20款产品,产品包括智能语音交互、图像识别、性能测试PTS、云数据库RDS等,其中事务消息降价90%&…

(Docker实战) 第四篇:建立持续集成环境01

标签: gblfy技术文档 文章目录一、 jenkins环境建立1.1. jenkins安装1.2. 安装jenkins前提:下载jdk1.3. 配置jenkins1.3.1. 配置远程发布插件Publish over SSH 选择系统设置1.3.2. 配置jdk,git,maven 选择系统管理->全局工具配…

系统无法分配所需内存_Innodb内存管理解析

本文主要介绍innodb的内存管理,涉及基础的内存分配结构、算法以及buffer pool的实现细节,提及change buffer、自适应hash index和log buffer的基本概念和内存基本配比,侧重点在内存的分配和管理方式。本文所述内容基于mysql8.0版本。基础内存…

飞天2.0面向万物智能的操作系统正式启幕

原文链接 本文为云栖社区原创内容,未经允许不得转载。

阿里数据总监分享《阿里数据中台建设实践案例》,PPT+语音讲解!

戳蓝字“CSDN云计算”关注我们哦!作者 | 技术领导力责编 | 阿秃本文整理自,阿里巴巴集团数据部商业应用总监列文,在“2019年阿里云(上海)峰会”上的分享,以PPT图片文字语音的方式呈现给各位社区读者。如果…

(Docker实战) 第五篇:建立持续集成环境02

标签: gblfy技术文档 文章目录一、 jenkins实战,持续集成实际项目1.1. 安装maven插件1.1.1. 找到Maven Integration这个插件1.1.2. 确保jenkins的maven本地仓库有一定的权限1.1.3. 创建job1.1.4. 配置参数1.1.5. 配置git仓库信息1.1.7. 配置构建信息1.1.…

阿里云OCR证件识别商业化发布,减少人工审核误差节省成本

随着互联网的发展,利用现代信息技术开展高效快捷便民服务工作,已经势在必行。证件识别算法,极大地提高了办公效率,现已在互联网金融、银行保险、电信通讯运营商、智能交通、政府、航空、社保局等行业领域被广泛运用。 近日&#…

(Docker实战) 第六篇:建立持续集成环境03

标签: gblfy技术文档 文章目录六、 git核心概念6.1. git学习地址6.2. github和码云的介绍6.3. git常用命令和操作6.3.1. 命令行常用命令6.3. IDEA操作方法(具体看视频)6.3.1. 合并分支6.3.2. compare with6.3.3. rename6.3.4. 看历史记录(所有的和单个文…

程序员:站在“自学”鄙视链顶端的王者

我在大学的时候,真的遇到一个神人,叫他小马吧。几乎没见过小马上课,第一节实验课就完成全学期所有实验,大一就自学大二课程,大四还没毕业就拿到了阿里offer,然后在我们苦兮兮找工作的时候,人家已…

用户需求源源不断,阿里云网络创新不止

2018杭州云栖大会,阿里云网络产品重点介绍了两个创新产品,智能接入网关和云企业网,以及全球领先的云网络系统-飞天洛神。智能接入网关是业内主要云服务商中第一家提供这样产品的,云企业网更是业内首创的多地域互联产品…

漫画:要跳槽?这道缓存设计题你有必要看看!

戳蓝字“CSDN云计算”关注我们哦!作者 | 程序员吴小胖责编 | 阿秃金九银十招聘季,社畜跳槽,学生出笼,也是非常热闹。不过今年继续互联网寒冬,能苟着还是苟着吧,猥琐发育别浪。苟着除了写Bug,还…

阿里云高级技术专家赵伟:安全加速 SCDN 设计与案例

此前,阿里云发布了SCDN安全加速解决方案,在CDN加速的基础上,将专业的安全能力赋能 CDN,实现既有加速又有安全的服务。在本次杭州云栖-飞天技术汇CDN与边缘计算专场中,阿里云高级技术专家赵伟从业务背景、架构设计和客户…