String对象的创建——再也不怕字符串的比较了

字符串的比较顺序
  • “==”用来比较两个变量的值是否相当,也就是运用该运算符比较变量,比较的是该变量对应内存中存储的数值是否相等(而变量是栈上的概念,所以可以理解成等号比较的是栈上的数据);

  • equals是object类提供的方法,它的实现也是==,而有的类将他复写了,所以才会有equals用于比较对象的内容;

  • 创建字符串最平常的方式:

   String str1 = "abcd";
   String str2 = new String("abcd");

区别是有的:
第一种方式引用的是常量池的对象;第二种方式会先在常量池中先查找能不能找到"abcd"或"abcd"的引用,如果没有,那么就会在常量池创建字符"abcd",然后在堆上创建对象,对象中存储常量池字符的地址,同时在栈上创建str2,str2存储堆上对象的地址(创建了两个对象);如果找到了在堆上放的就是常量池的引用(创建了一个对象);

  • 变形:
	String str1 = "ab"+"cd";
	String str2 = new String("ab")+new String("cd");
  • 第一句在编译时已经将"ab"+"cd"换成"abcd"所以和String str1 = “abcd”;是一模一样的;
  • 而第二句: 会在常量池中创建ab、cd并在堆上存储ab和cd在常量池的引用, 在栈上创建引用变量str2 ,而str2 引用的对象实体是"abcd",因此会在堆上创建"abcd",同时把"abcd"的地址复制给str2 ;
    注意此时并没有把"abcd"放在字符串常量池中;
	String str1 =new String("ab");
   String str2 = new String("str1");
总结

无论如何只要是new 出来的string那么就会在堆上开辟空间,那么他在栈上的引用,引用的就是不同存储地址,所以当用s1==s2时都是false;

string比较
String s1 = "AB";
System.out.println(s1=="AB");//true
String s1 = new String("AB");
System.out.println(s1=="AB");//false

当我还在思考这个字面值常量“AB”,程序有没有为他开辟一个空间时(或者开辟的空间在哪里?)通过上面的代码已经验证了这个空间是存在的,它就是常量池;忽然间往事历历在目,所有的字面值常量都是存储在常量池中的;那么常量池中存储的都有什么?一种是字面值常量,一种的符号引用;

  • 字面值常量:
    • 文本字符串
    • 被声明为final的值
    • 基本数据类型值
  • 符号引用
    • 类的结构和完整限定名
    • 字段名称和描述符;
    • 方法名称和描s述符;
      那么再看这段代码:
String s1=new String("A")+new String("B");      
System.out.println(s1=="AB");

此时的"AB"已经有自己的常量池空间了(可以看作一个匿名对象),那么s1=="AB"时堆上的“AB”和常量是的“AB”就很显然不一样了结果为false;

		String s1=new String("A")+new String("B");
        System.out.println(s1==s1.intern());
        System.out.println(s1=="AB");

此时话音戛然而止,意犹未尽着,更多精彩请看我的另一篇文章让人望而却步的String及intern()方法

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值