java中的String对象,你到底了解多少?

「JDK」解析 String str=““与 new String() 一、基础概念 为了讲清楚他们的差异,这里先介绍几个概念。 1.1 常量池 所谓常量池:顾名思义就是用来存放一些常量的。该常量是在编译期被确定,并被保存在已编译的.class文件中,其中包括了类,方法,接口等包含的数值常量,字符常量和字符串常量。 1.2 字符串常量池 在常量池中,有个专门用来存储字符串常量的,称之为字符串常量池。 当我们需要使用字符串时,首先会在该字符串常量中查找是否存在该字符串,若存在则直接进行使用;若不存在,则会新建一个对应的字符串,并保存在该字符串常量池中。 1.3 阅读详情

          1. 首先String不属于8种基本数据类型,String是一个对象。

   因为对象的默认值是null,所以String的默认值也是null;但它又是一种特殊的对象,有其它对象没有的一些特性。

   2. new String()和new String(“”)都是申明一个新的空字符串,是空串不是null;

   3. String str=”kvill”;
              String str=new String (“kvill”);的区别:

        在这里,我们不谈堆,也不谈栈,只先简单引入常量池这个简单的概念。

   常量池(constant pool)指的是在编译期被确定,并被保存在已编译的.class文件中的一些数据。它包括了关于类、方法、接口等中的常量,也包括字符串常量。

   看例1:

 

String s0=”kvill”;
String s1=”kvill”;
String s2=”kv” + “ill”;
System.out.println( s0==s1 );
System.out.println( s0==s2 );


   结果为:


true
true


   首先,我们要知道Java会确保一个字符串常量只有一个拷贝。

   因为例子中的s0和s1中的”kvill”都是字符串常量,它们在编译期就被确定了,所以s0==s1为true;而”kv”和”ill”也都是字符串常量,当一个字符串由多个字符串常量连接而成时,它自己肯定也是字符串常量,所以s2也同样在编译期就被解析为一个字符串常量,所以s2也是常量池中”kvill”的一个引用。

   所以我们得出s0==s1==s2;

   用new String() 创建的字符串不是常量,不能在编译期就确定,所以new String() 创建的字符串不放入常量池中,它们有自己的地址空间。

   看例2:


String s0=”kvill”;
String s1=new String(”kvill”);
String s2=”kv” + new String(“ill”);
System.out.println( s0==s1 );
System.out.println( s0==s2 );
System.out.println( s1==s2 );


   结果为:


false
false
false


   例2中s0还是常量池中”kvill”的应用,s1因为无法在编译期确定,所以是运行时创建的新对象”kvill”的引用,s2因为有后半部分new String(“ill”)所以也无法在编译期确定,所以也是一个新创建对象”kvill”的应用;明白了这些也就知道为何得出此结果了。

   4. String.intern():

   再补充介绍一点:存在于.class文件中的常量池,在运行期被JVM装载,并且可以扩充。String的intern()方法就是扩充常量池的一个方法;当一个String实例str调用intern()方法时,Java查找常量池中是否有相同Unicode的字符串常量,如果有,则返回其的引用,如果没有,则在常量池中增加一个Unicode等于str的字符串并返回它的引用;看例3就清楚了

   例3:


String s0= “kvill”;
String s1=new String(”kvill”);
String s2=new String(“kvill”);
System.out.println( s0==s1 );
System.out.println( “**********” );
s1.intern();
s2=s2.intern(); //把常量池中“kvill”的引用赋给s2
System.out.println( s0==s1);
System.out.println( s0==s1.intern() );
System.out.println( s0==s2 );


   结果为:


false
**********
false //虽然执行了s1.intern(),但它的返回值没有赋给s1
true //说明s1.intern()返回的是常量池中”kvill”的引用
true


   最后我再破除一个错误的理解:

   有人说,“使用String.intern()方法则可以将一个String类的保存到一个全局String表中,如果具有相同值的Unicode字符串已经在这个表中,那么该方法返回表中已有字符串的地址,如果在表中没有相同值的字符串,则将自己的地址注册到表中“如果我把他说的这个全局的String表理解为常量池的话,他的最后一句话,“如果在表中没有相同值的字符串,则将自己的地址注册到表中”是错的:

   看例4:


String s1=new String("kvill");
String s2=s1.intern();
System.out.println( s1==s1.intern() );
System.out.println( s1+" "+s2 );
System.out.println( s2==s1.intern() );


   结果:


false
kvill kvill
true


   在这个类中我们没有声名一个”kvill”常量,所以常量池中一开始是没有”kvill”的,当我们调用s1.intern()后就在常量池中新添加了一个”kvill”常量,原来的不在常量池中的”kvill”仍然存在,也就不是“将自己的地址注册到常量池中”了。

   s1==s1.intern()为false说明原来的“kvill”仍然存在;

   s2现在为常量池中“kvill”的地址,所以有s2==s1.intern()为true。

   5. 关于equals()和==:

   这个对于String简单来说就是比较两字符串的Unicode序列是否相当,如果相等返回true;而==是比较两字符串的地址是否相同,也就是是否是同一个字符串的引用。

   6. 关于String是不可变的

   这一说又要说很多,大家只要知道String的实例一旦生成就不会再改变了,比如说:String str=”kv”+”ill”+” “+”ans”;
就是有4个字符串常量,首先”kv”和”ill”生成了”kvill”存在内存中,然后”kvill”又和” “ 生成 ”kvill “存在内存中,最后又和生成了”kvill ans”;并把这个字符串的地址赋给了str,就是因为String的“不可变”产生了很多临时变量,这也就是为什么建议用StringBuffer的原因了,因为StringBuffer是可改变的 。

转自http://hi.baidu.com/large9331/blog/item/673942162296524b21a4e91c.html

介绍String String实例化的两种方式 String name1 = "haoren"; ①String name2 = new String("huairen"); 两种实例化的区别 String name1 = "haoren"; String name2 = "haoren"; name1和name2指向了同一空间,“haoren”只存储了一次 java对直接定义字符串做优化:如果两个变量的值相同在内存中只存储了一次,所以两个变量的地址相同 ... 阅读详情

相关推荐

【斯坦福计网CS144项目】环境配置 & Lab0: ByteStream

前言 感觉学了不少 C++ 编程的知识和技术但比较缺少实践,于是打算找一些项目跟着做一做。 首先安利一个自学网站 CS自学指南,北大的同学做的,汇总了很多国内外高校 CS 相关的高质量公开课,其中大部分是有课程项目的。翻了翻感觉 Stanford 的这门 CS144 计网课的 Lab 比较有趣,难度也不错,就是它了! 课程网址:CS 144: Introduction to Computer Networking 我跟的是 2021 Fall 学期的版本。 准备工作 在上面的网站中先把 8 个实验的文档(

アルタイル 8132

详解Java中的String数据类型

【摘 要】本文详细介绍详解Java中的String数据类型的文章专题。1. 首先String不属于8种基本数据类型,String是一个对象。    因为对象的默认值是null,所以String的默认值也是null;但它又是一种特殊的对象,有其它对象没有的一些特性。    2. new String()和new String(“”)都是申明一个新的空字符串,是空串不是null;    3. Stri

pobu26的专栏 1050

String类你了解多少

String类型不属于基本数据类型之一,它实际上是对数组的特殊包装,是一个匿名对象。 1、String类的两种实例化方式及区别 第一种: 直接赋值 String str1 = "haha"; String str2 = "haha"; System.out.println(str1 == str2); //true 以上结果是true,也就是虽然定义了两个字符串对象,但实际...

697

傻傻分不清楚?: 一文看懂JavaString的New操作和直接赋值字符串的区别

简介 String str=new String(“a”)和String str = "a"有什么区别? String s = new String(“xyz”);创建了几个StringObject? 这条语句一共创建了多少对象String s=“a”+“b”+“c”+“d”; String s1 = "a"; String s2 = s1 + "b"; s2 == “ab” 吗? 是不是被上面的题目逼疯了,哈哈,微观Java对考查Java变量初始化原理十分普遍,不过不用着急,本篇文章赋予你杀虫

OxYGC 2525

java String中new和直接赋值的区别

在此之前,我们要知道的是,String是不可变对象,只要创建就不能修改,所有的修改操作实际上都是新建的String对象. 1.直接赋值 String myString = "hello world"; 原理是:现在java的常量池中寻找hello world对象,如果没有,在堆内存中new一个值为”hello world” 的对象,放到常量池中. 之后再用直接赋值的方法时,如果值相同,就直接...

fly_fly_fly_pig的博客 1万+

Java String 对象,你了解多少

String对象Java 中使用最频繁的对象之一,所以 Java 公司也在不断的对String对象的实现进行优化,以便提升String对象的性能,看下面这张图,一起了解一下String对象的优化过程。 Java String 对象,你真的了解了吗? 在 Java6 以及之前的版本中 String对象是对 char 数组进行了封装实现的对象,主要有四个成员变量:char 数组、偏移量 off...

weixin_45560122的博客 210

java string 字符串比较_Java String字符串比较问题?

题主你只要知道有个叫常量池的东西就行了,类似String a = "helloworld"里的helloworld在虚拟节规范中叫字面量,不管你定义多少="helloworld"的变量,都是指向的同一个地址。你的例子还可以稍微改一下:String a = "hello";String b = "world";String ab = "helloworld";System.out.println(a...

weixin_34342860的博客 167

Java String 对象,你真的了解了吗?

String 对象的实现 String对象Java 中使用最频繁的对象之一,所以 Java 公司也在不断的对String对象的实现进行优化,以便提升String对象的性能,看下面这张图,一起了解一下String对象的优化过程。 1. 在 Java6 以及之前的版本中 String对象是对 char 数组进行了封装实现的对象,主要有四个成员变量: char 数组、偏移量 offset、字符数量...

平头哥的技术博文 1万+

关于String了解多少

这是本人第一次写博客,以后陆续会写java源码(java8)的解析文章,纯手打,希望大家多多关注。 文章从两大方面讲解,1、介绍,2、源码解析 String类代表了java中的字符串, 一、String特点 1、不可变类,线程安全。 不可变类在语言层面怎么实现的呢?这里用到了java的final关键字,final有三个作用,简单的说修饰的类不可继承,方法不可重写,变量不可修改。而String类和存储字符数据的Char数组就是用final修饰的,string类不可继承,内部数据(char数组)不能修

weixin_32300523的博客 4308

java中的string对象深入了解

这里来对Java中的String对象做一个稍微深入的了解Java对象实现的演进 String对象Java中使用最频繁的对象之一,所以Java开发者们也在不断地对String对象的实现进行优化,以便提升String对象的性能。 Java6以及之前版本中String对象的属性 在Java6以及之前版本中,String对象是对char数组进行了封装实现的对象,其主要有4个成员成员变量,分别是char数组、偏移量offset、字符数量count和哈希值hash。String对象是通过offset和

m0_37154839的博客 333

深入了解java中的String对象

原帖地址http://blog.pfan.cn/txdnet/36493.html一,从根本上认识java.lang.String类和String池 首先,我建议先看看String类的源码实现,这是从本质上认识String类的根本出发点.从中可以看到: 1,String类是final的,不可被继承.public final class String. 2,String类是的本质是字符数组c

alvetjook的专栏 629

String类之那些你不知道的知识点

  关于Java JDK中内置的一个类:java.lang.String我们需要了解的有以下几点: String表示字符串类型,属于引用数据类型,切记不属于基本数据类型; 在java中随便使用双引号 “” 括起来的都是String类型的对象。例如"abc"、“张三”、“HelloWorld”,这是三个String对象java中规定,双引号括起来的字符串是不可变的,也就是说“abc”这个字符串自出生到死亡这个过程都是不可变的,不可能再变成“abcd”; 在JDK当中双引号括起来的字符串都是直接存储下 “

hpf_coding的博客 552

String类型直接赋值跟使用new的区别

方式二:先在堆中创建空间,维护了value属性,value指向常量池的abc空间,如果常量池没有"abc",创建后指向,如果有直接通过value指向。s2 最终指向的是堆中的空间地址,堆中维护的value指向的是常量池中的"abc"。方式一:先从常量池里面查看是否有"abc"数据空间,如果有,直接指向;如果没有则创建后指向。s1最终指向的是常量池里的空间地址。方式二:调用构造器 String s2 = new String ("abc")方式一:直接赋值 String s1 = "abc"

weixin_53425597的博客 267

javaString与new String的区别

String类:表示不可改变的字符串,当前对象创建完毕之后,该对象的内容(字符序列)是不能改变的,一旦内容改变就是一个新的对象String对象的创建: 1):直接赋一个字面量: String str1 = “ABCD”; 2):通过构造器构造:String str = new String(“ABCD”); 面试题1:两种方式有什么区别,分别在内存中...

dreamzuora的博客 2万+

Java定义字符串:String 和 new String()的区别

了解三个不同存储区: 栈区:存放基本类型和引用类型的引用地址。 堆区:存放对象 字符串常量池: 1.直接使用双引号声明出来的String对象会直接存储在常量池中。 2.如果不是用双引号声明的String 对象,可以使用String 提供的intern方string.intern()。 它的作用是:如果运行时常量池中已经包含一个等于此String对象内容的字符串,则返回 常量池中该字符串的引用;如果没有,则在常量池中创建与此 String内容相同的字符串, 并返回常量池中创建的字符串的引用。

weixin_44057803的博客 2240

JavaString和new String的不同。

通过上述的描述,相信大部分人对于文章开头的问题已经有了答案。所以总结就是String x="a"和new String("a")是不相同的。

m0_65839118的博客 725

string 和new String 区别

主要区别是: //字符串一样,但存储位置不一样,相当于当两个值 String a = new String("ab"); // a 为一个引用 String b = new String("ab"); // b为另一个引用,对象的内容一样 //字符串一样,存储位置也一样,相当于一个值 String aa = "ab"; // 放在常量池中 String bb = "ab"; // 从常...

qq_33416416的博客 1512

【软考高级架构】论文范文12——论生成式AI在软件开发中的应用与挑战

随着生成式AI技术的跨越式发展,以大语言模型为代表的生成式AI正在深刻改变软件开发的传统模式。在代码生成、测试构造、文档编写等环节,生成式AI展现出显著的效率提升潜力,但其应用也面临着代码质量不可控、安全漏洞植入、版权合规等严峻挑战。本文以笔者主导的某大型金融企业智能研发辅助平台建设项目为案例,围绕生成式AI在软件开发中的应用实践与应对挑战的策略展开论述。笔者担任系统架构师,负责平台架构设计、模型选型、质量保障机制及安全防线构建。

qq837993702的博客 233

省、市数字普惠金融指数(2011-2024年).xlsx

详细介绍及样例数据:https://blog.csdn.net/li514006030/article/details/159383486

上一篇: MySQL查询优化系列讲座之查询优化器
open_source
博客等级 码龄19年 0粉丝 1原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值