首页 > 其他分享 > String基础: String两种创建对象方式的比较

String基础: String两种创建对象方式的比较

时间:2022-10-29 00:15:02浏览次数:56  
标签:两种 String 创建对象 equals 字符串 strB strA public

  • 字符串常量

在一般的语言中常量一旦声明则不可改变,在java中的字符串常量是以匿名对象来表示的

javaz中字符串两种定义方法:

  1. String strA= new String("hello");(符合习惯的声明方法)
  2. String strA="hello";(常用的声明方法)

一个基本事实:在java中字符串常量的本质是String类型的匿名对象

  • 基本解释:习惯的定义方法和前面的一样,常用的定义方法中,将用于储存匿名对象"hello"的堆空间的使用权交给strA,strA指向该匿名空间

其实这里聪明的小伙伴已经发现了两者的差异了,在习惯声明的方式中,"hello"不仅是作为匿名对象,还会为new关键字开辟的对象所赋值
所有说习惯性的声明方法开辟了2次的内存空间

小插曲---分析字符串的比较

了解完上面的概念,对应字符串的比较就没有什么压力了

例子的引出

 //分析字符串中==运算符
public class Compare{
	public static void main(String[]args){
		
		String strA="yootk";
		String strB=new String("yootk");
		String strC=strB;//进行引用传递指向strB所指向的堆地址
		System.out.println(strA==strB);//false
		System.out.println(strC==strB);//true
		System.out.println(strA==strC);//false
		
		
	}
} 

内存指向分析

从前面的分析和空间的内存分析可以看出==运算符在字符串中是直接进行地址的比较的,其实也不难理解strA strB strC是该类对象的引用,储存的是对应的堆空间的地址,直接这样比较不就是比较地址吗

得到一个结论:==运算符在java中用于对象地址的比较

进行字符串内容的比较可以用String类的内置函数 equals()

该函数定义方式:Public boolean equals(Setring str)

根据两字符串的数值是否相等返回false或者true

 //分析字符串中==运算符
public class Compare{
	public static void main(String[]args){
		
		String strA="yootk";
		String strB=new String("yootk");
		String strC=strB;//进行引用传递指向strB所指向的堆地址
		System.out.println("yootk".equals(strB));//true
		System.out.println("yootk".equals(strB));//true
		System.out.println("yootk".equals(strC));//true
		
		
	}
} 

用equals完美的解决了问题,同时可以发现equals()函数是由"yootk"来调用的,也可以验证字符串常量就是一个匿名对象

建议当字符串常量和字符串变量在进行equals比较时,用字符串常量进行equals函数的调用,也就是将常量写在前面

原因:当输入的字符串没有进行实例化或者说没有被赋值的时候,此时字符串=null,此时如果进行equals方法的调用,就会出现空指针异常

public class Compare{
	public static void main(String[]args){
		String strA=null;
	    //后面没有进行实例化
		System.out.println(strA.equals("hello"));
	}
}

解决:用字符串常量进行equals方法调用,字符串常量本质上就是一个匿名对象永远不可能为空

public class Compare{
	public static void main(String[]args){
		String strA=null;
	 
		System.out.println("hello".equals(strA));//false 该处输入的strA为 空直接返回false
	}
}

而且还有一个好处:equals()方法内部会自动进行Null的判断,所有这个时候如果发现输入的内容为空则直接返回false

两种声明方式的比较

问题的引出

public class Compare{
	public static void main(String[]args){
		String strA="yook.com";
		String strB="yook.com";
		System.out.println(strA==strB);//true
		System.out.println(strB=="yook.com");//true
	}
}

两个对象的地址相同,说明strA和strB都指向同一个对象

此时内存结构如图:

对于该情况的解释:


该处就相当于strB=strA 进行了引用传递 而没有开辟新的堆空间

用这种设计可以看出,当定义的多个常量值相同的时候都使用的是同一个对象,可以极大的节省内存空间的使用

分析:String strA=new String("hello")

用这种方式来定义字符串,前面已经解释了"hello"是一个匿名对象,当存在一个匿名对象会自动开辟一个堆空间储存hello,然后又通过new关键字开辟了一次堆空间,"hello"为堆空间赋值然后将new开辟的堆空间的地址给strA

可以从上述的分析中可以看到这种方式定义的字符串会多开辟一段空间,多开辟的空间将成为垃圾空间,会造成性能问题

通过new关键字声明的字符串不会进入常量共享池,java提供了一个手工入池的操作

总结:

分析:字符串常量池

*静态常量池举例*
public class Compare{
	public static void main(String[]args){
		String strA="helloworld";
		String strB="hello"+"world";
		System.out.println(strA==strB);//true
	}
}

动态常量池举例

public class Compare{
	public static void main(String[]args){
		String strA="hello";
		String strB=strA+"world";
		String strC="helloworld";
		System.out.println(strB==strC);//false
	}
}

如果以后编写字符串过长的时候用+链接最方便

public class Compare{
	public static void main(String[]args){
		String strA="today "+" is"+ " a" +" good"+ "  day!";
		System.out.println(strA);
	}
}

此时的程序是不会产生多个对象的,仅仅形成一个字符串常量,不影响程序的性能

标签:两种,String,创建对象,equals,字符串,strB,strA,public
From: https://www.cnblogs.com/swtaa/p/16835762.html

相关文章

  • 今天,念念不忘一件事... ✅FastJson在调用JSON#toJSONString时,如何截取比较长的value串
    项目里前后端页面的http请求及dubbo服务间的RPC调用,返回值类型统一是一个Result<T>,其结构如下。@DatapublicclassResult<T>implementsSerializable{priv......
  • 【ABC196F】Substring 2(多项式乘法)
    我竟然能在AT当场做出F题!哦,是ABC啊,没事了。以下的字符串均从\(1\)开始记位。以下设\(S_i\)表示字符串\(S\)的第\(i\)位,\(S(l,r)\)表示字符串\(S\)的第......
  • Wireshark解密HTTPS流量的两种方法
    原理我们先回顾一下SSL/TLS的整个握手过程:Clienthello:发送客户端的功能和首选项给服务器,在连接建立后,当希望重协商、或者响应服务器的重协商请求时会发送。versio......
  • C# 从死磕到精通系列 string 类型
    首先看下string类型支持的常见方法:像:1.ToString将其他类型转换为string类型。null不可转。(据说现在最新版可以支持了)    2.Split  根据指定字符切换字符串返......
  • getline与stringstream的用法
    https://www.acwing.com/problem/content/922/#include<bits/stdc++.h>usingnamespacestd;constintN=505;intn,m;intdist[N],stop[N],q[N];boolg[N]......
  • javaSE13-- API_常用类--默认继承Object--toString()--==与equals()[详解]
    API_常用类API应用程序编程接口API文档是对Java预定定义的类或接口功能和方法功能的说明文档,目的是提供给开发人员进行使用帮助说明默认继承Object,Java中所有类没有显示的......
  • String 转Array&Array转String
    String转为List,根据分隔符分割示例:Stringsn="1234,567,8910";List<String>snList=Arrays.asList(sn.split(","));1234,567,8910#List转为String,插入分隔符......
  • kubenetes service服务发现两种方式
    service服务发现ClusterIP方式1.暴露deployment服务kubectlexposedeploymentnginx4--port=8000--target-port=80等同于kubectlexposedeploymentnginx4--po......
  • 4.IOC创建对象的方式
    4.IOC创建对象的方式  配置beans.xml(基于XML的配置元数据的基本结构:)<?xmlversion="1.0"encoding="UTF-8"?><beansxmlns="<http://www.springframework.org/sc......
  • string ArrayList 总结
    API:程序编程接口,方便调用string类:“”相同内容存储一份(减少浪费,共享)堆内存中的常量池中new出来的放在堆内存中      常用方法:equals等等(==判断......