java new string 图_Java中String直接赋字符串和new String的一些问题
今天课堂测试做了几道String的练习题,做完直接心态爆炸......
整理自下面两篇博客:
首先先来看看下面的代码:
public classStringTest {public static voidmain(String[] args){
String s1="Hello";
String s2="Hello";
String s3=new String("Hello");
System.out.println("s1和s2 引用地址是否相同:"+(s1 ==s2));
System.out.println("s1和s2 值是否相同:"+s1.equals(s2));
System.out.println("s1和s3 引用地址是否相同:"+(s1 ==s3));
System.out.println("s1和s3 值是否相同:"+s1.equals(s3));
}
}
打印结果如下:
s1和s2 引用地址是否相同:trues1和s2 值是否相同:trues1和s3 引用地址是否相同:falses1和s3 值是否相同:true
我们可以看到 在java中,比较String有两种方式,一种是用"==",另一种是用s.equals()方法。
那么这两种方法有什么不同呢?
上面程序中的"=="是判断两个对象引用的地址是否相同,也就是判断是否为同一个对象,s1与s2 返回为true,s1与s3返回则是false。说明s1与s2 引用的同一个对象的地址,s3则与其它两个引用不是同一个对象地址。
而s.equals()方法则是判断字符串的内容是否相等,只要内容相等就返回true,当然,地址相等就更不用说了,肯定返回true。
Java为了避免产生大量的String对象,设计了一个字符串常量池。工作原理是这样的,创建一个字符串时,JVM首先为检查字符串常量池中是否有值相等的字符串,如果有,则不再创建,直接返回该字符串的引用地址,若没有,则创建,然后放到字符串常量池中,并返回新创建的字符串的引用地址。所以上面s1与s2引用地址相同。
那为什么s3与s1、s2引用的不是同一个字符串地址呢?
注意看 s3的定义方法:
String s3=new String("Hello");
JVM首先是在字符串常量池中找"Hello" 字符串,如果没有创建字符串常量,然后放到常量池中,若已存在,则不需要创建;当遇到 new 时,还会在内存(不是字符串常量池中,而是在堆里面)上创建一个新的String对象,存储"Hello",并将内存上的String对象引用地址返回,所以s3与s1、s2引用的不是同一个字符串地址。 内存结构图如下:
从内存图可见,s1与s2指向的都是常量池中的字符串常量,所以它们比较的是同一块内存地址,而s3指向的是堆里面的一块地址,说的具体点应该是堆里面的Eden区域,s1跟s3,s2跟s3比较都是不相等的,都不是同一块地址。
拓展问题:
请问String s = new String("xyz");产生了几个对象?
在String的工作原理中,已经提到了,new一个String对象,是需要先在字符串常量中查找相同值或创建一个字符串常量,然后再在内存堆中创建一个String对象,所以String s = new String("xyz"); 会创建两个对象。
下面看几道习题:
1、
public classTest {public static voidmain(String[ ] args) {
String s1= new String("Welcome to Java!");
String s2= new String("Welcome to Java!");if (s1 ==s2)
System.out.println("s1 and s2 reference to the same String object");elseSystem.out.println("s1 and s2 reference to different String objects");
}
}
s1 and s2 have different contents
虽然常量池中已经存在"Welcome to Java!"了,但s2 new 时,还会在内存(不是字符串常量池中,而是在堆里面)上创建一个新的String对象,存储"Welcome to Java!",并将内存上的String对象引用地址返回给s2,所以s1和s2引用地址不同。
2、
public classTest {public static voidmain(String[ ] args) {
String s1= "Welcome to Java!";
String s2=s1;if (s1 ==s2)
System.out.println("s1 and s2 reference to the same String object");elseSystem.out.println("s1 and s2 reference to different String objects");
}
}
s1 and s2 reference to the same String object
常量池中已经存在"Welcome to Java!"了,不需要再创建,直接返回该字符串的引用地址给s2,所以s1和s2有相同的引用地址。
再来看这样一个问题:
public classTest {public static voidmain(String[] args) {
String s1= "hello";
String s2= "world";
String s3= "helloworld";
System.out.println(s3== s1 + s2);//false
System.out.println(s3.equals((s1 + s2)));//true
System.out.println(s3 == "hello" + "world");//ture
System.out.println(s3.equals("hello" + "world"));//true
}
}
equals()比较方法不解释,比较值,均相等,均为true。
s1与s2相加是先在字符串常量池中开一个空间,然后拼接,这个空间的地址就是s1与s2拼接后的地址。与s3的地址不同,所以输出为false。
s3与”hello”+”world”作比较,”hello”+”world”先拼接成”helloworld”,然后再去字符串常量池中找是否有”helloworld”,有,所以和s3共用一个字符串对象,则为true。
总结:
String s = new String(“hello”)会创建2(1)个对象,String s = “hello”创建1(0)个对象。
注:当字符串常量池中有对象hello时括号内成立!
字符串如果是变量相加,先开空间,在拼接。
字符串如果是常量相加,是先加,然后在常量池找,如果有就直接返回,否则,就创建。
java new string 图_Java中String直接赋字符串和new String的一些问题相关推荐
- java 数组 length 减少_java中数组有没有length()方法?string没有lenght()方法?
java中数组有没有length()方法,求数组的长度可以使用数组的length属性. int length=arr.length;//求数组的长度 ------------------------- ...
- java如何获取手机号码_java中如何提取一个字符串中的电话号码?
展开全部 java中如何提取一个字符串中的电话号码e68a84e8a2ad3231313335323631343130323136353331333363376466,先写出手机号码和固定号码的正则表 ...
- java stringbuffer长度限制_Java中的String、StringBuffer和StringBuilder
作为作为一个已经入了门的java程序猿,肯定对Java中的String.StringBuffer和StringBuilder都略有耳闻了,尤其是String 肯定是经常用的.但肯定你有一点很好奇,为什 ...
- java中string类_Java中String类浅谈
1)String对象的初始化 由于String对象特别常用,所以在对String对象进行初始化时,Java提供了一种简化的特殊语法,格式如下: String s = "abc&qu ...
- java string类型_java中String类型
String类型是字符串类型..字符串一旦创建不可以在改变."abc"字符串对象一旦创建,不可以再改成"abcd" 提升字符串的访问效率:在程序中使用了&quo ...
- java new string作用_java中直接new String对象?
首先明确一点,在Java中==比较的是两个对象的地址,equals()比较的是两个对象的值,如果使用equals()来替换==,则两个输出结果都为true. 言归正传,为什么第一个返回为false? ...
- Java中string与String区别_JAVA中String与StringBuffer的区别
JAVA中String与StringBuffer的区别 2009-12-3文字大小:大中小 在java中有3个类来负责字符的操作. 1.Character 是执行 单个字符操作的, 2.String ...
- java中string范围_java中long parseLong(String s)方法中string(十进制数字)的范围?
java中long parseLong(String s)方法中string(十进制数字)的范围? 來源:互聯網 2009-06-19 05:05:28 評論 分類: 電腦/網絡 >> ...
- java的string类_Java中的String类笔记
说明 源码 //jdk8 public final class String implements java.io.Serializable, Comparable, CharSequence { / ...
最新文章
- Ubuntu快速重装软件的技巧
- web安全_皮卡丘_xss
- 中国宜坚持发展自主操作系统
- Java基础5一数组的常见应用算法
- springMVC中添加命名空间(edit namespace)
- 编程利器 Beyond Compare 的使用
- 机器学习中的概率模型和概率密度估计方法及VAE生成式模型详解之二(作者简介)...
- NHibernate.3.0.Cookbook第一章第六节Handling versioning and concurrency的翻译
- VMware Fusion CentOS7 下载安装及手动配置静态IP
- 使用arecord、aplay命令实现音频的采集和播放
- APICloud常用
- 安卓和ios的ui设计区别_UI设计中IOS和安卓的设计差异
- re正则表达式必备基础知识
- 机柜风扇 的组成及如何正确安装 机柜散热风扇
- 从感知机到Transformer,一文概述深度学习简史
- 【计算机网络】谢希仁笔记 运输层
- JSP程序+tomcat服务器如何禁止客户端访问非页面形式路径
- phprm=20161221
- 金融粉去哪里引流?哪个平台做金融引流好?贴吧精准引流金融粉技巧
- OpenHarmony开源鸿蒙与HarmonyOS商业鸿蒙的区别