栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java——常用类String及方法(详细分析)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java——常用类String及方法(详细分析)

目录
  • String类特点
    • String类型不能被继承,因为String是由final修饰的
    • String类型的对象是不可变的
      • 常量池
      • 字符串常量池在哪里?
      • String对象为什么不可变?
  • String对象创建个数与拼接结果
    • 对象创建
    • 拼接
    • 空字符串
  • String对象的比较
  • String类常用方法

java.lang.String

String类特点 String类型不能被继承,因为String是由final修饰的 String类型的对象是不可变的

换句话说,只要修改字符串,就会产生新对象

@Test
    public void test01(){
        String s  = "你好";
        change(s);
        System.out.println(s);//你好
    }
    public void change(String str){
        str = "hello";
    }
常量池

String对象不可变的特性,使得我们可以把一些字符串存到常量池中——字符串常量池。常量池中的数据是可以共享的。

@Test
	public void test02(){
		String s1 = "hello";
		String s2 = "hello";		
		System.out.println(s1 == s2)//true;
		//地址是同一个
	}
字符串常量池在哪里?

Oracle官方虚拟机HotSpot
(1)JDK1.6以及之前:方法区
(2)JDK1.7:挪到堆中,即在堆中单独划分了一块来存字符串常量
(3)JDK1.8:从堆中挪出,挪到一个“元空间meta space”,即类似于方法区

String对象为什么不可变?

①底层char[]数组有final修饰,意味着这个数组不能扩容等,来达到存储更多的字符。——无法扩容

②char[]数组是私有的,我们无法直接操作这个char[]数组,而且String没有提供这样的方法,来修改char[]数组的元素的值。——无法修改

部分源码:

public final class String
    implements java.io.Serializable, Comparable, CharSequence {
    
    private final char value[];


//无参构造函数,默认创建一个空字符串
 public String() {
        this.value = "".value;
    }

public String(String original) {
        this.value = original.value;
        this.hash = original.hash;
    }

... ... 
}

String提供的所有的方法,对字符串的修改都是返回一个新的字符串对象。

String对象创建个数与拼接结果 对象创建
String str = "hello";//一个字符串对象

栈中存储的是常量池中char[]的地址。


String str = new String("hello");//两个字符串对象

一个在常量池中:hello。另一个在堆中,String的对象
堆中的这个字符串对象char[]的value数组,指向常量池中"hello"的char[]的value

栈中存储的是堆中对象的地址

拼接

拼接的结果在堆还是在常量池?
(1)常量 + 常量在常量池
(2)变量 +常量在堆
(3)变量 + 变量在堆
(4)xx.intern():在常量池

@Test
	public void test06(){
		String s1 = "hello";
		String s2 = "world";
		String s3 = "helloworld";
		
		String s4 = (s1 + "world").intern();//把拼接的结果放到常量池中
		String s5 = (s1 + s2).intern();
		
		System.out.println(s3 == s4);//true
		System.out.println(s3 == s5);//true
	}
	
	@Test
	public void test05(){
		final String s1 = "hello";
		final String s2 = "world";
		String s3 = "helloworld";
		
		String s4 = s1 + "world";//s4字符串内容也helloworld,s1是常量,"world"常量,常量+ 常量 结果在常量池中
		String s5 = s1 + s2;//s5字符串内容也helloworld,s1和s2都是常量,常量+ 常量 结果在常量池中
		String s6 = "hello" + "world";//常量+ 常量 结果在常量池中,因为编译期间就可以确定结果
		
		System.out.println(s3 == s4);//true
		System.out.println(s3 == s5);//true
		System.out.println(s3 == s6);//true
	}
	
	@Test
	public void test04(){
		String s1 = "hello";
		String s2 = "world";
		String s3 = "helloworld";
		
		String s4 = s1 + "world";//s4字符串内容也helloworld,s1是变量,"world"常量,变量 + 常量的结果在堆中
		String s5 = s1 + s2;//s5字符串内容也helloworld,s1和s2都是变量,变量 + 变量的结果在堆中
		String s6 = "hello" + "world";//常量+ 常量 结果在常量池中,因为编译期间就可以确定结果
		
		System.out.println(s3 == s4);//false
		System.out.println(s3 == s5);//false
		System.out.println(s3 == s6);//true
	}
空字符串

(1)""
(2)new String()
(3)new String("")

@Test
	public void test07(){
		String s1; //局部变量未初始化
		String s2 = null;//初始化null
		String s3 = "";//空字符串常量对象
		String s4 = new String();//空字符串对象
		String s5 = new String("");//两个对象,一个是常量池中的,一个是堆中
		
      //System.out.println(s1);//无法使用
      //System.out.println(s2.length());//空指针异常
		
		System.out.println(s3.length());
		System.out.println(s4.length());
		System.out.println(s5.length());
	}

判断空字符串
四种方式:
(1)if(str != null && str.length() == 0)

(2)if(str != null && str.equals(""))
(3)if("".equals(str)) 推荐

(4)if(str!=null && str.isEmpty())

String对象的比较

(1)==:比较对象的地址
结论:只有两个字符串的常量对象比较时才会返回true,其他的都是false

(2)equals:比较字符串的内容,严格区分大小写
因为String类型重写了Object的equals

==与equals的详细分析和区别,请参考文章:equals与==的区别.

(3)equalsIgnoreCase(String anotherString) :比较字符串内容,不区分大小写

(4)大小比较,严格区分大小写
String类型实现了Comparable接口,重写了compareTo方法,严格区分大小写

@Test
	public void test06(){
		String s1 = new String("hello");
		String s2 = new String("helloworld");	
	
		
		if(s1.compareTo(s2) > 0){
			System.out.println(s1 + ">" + s2);
		}else if(s1.compareTo(s2) < 0){
			System.out.println(s1 + "<" + s2);
		}else{
			System.out.println(s1 + "=" + s2);
		}	
		//hello 

依次比较对应位置的字符
hello和Hello,先[0]位置的h和H,h>H,就直接认定hello>Hello
否则继续按位比较。

(5)大小比较:不区分大小写

@Test
	public void test07(){
		String s1 = new String("hello");
		String s2 = new String("Hello");
		
		if(s1.compareToIgnoreCase(s2) > 0){
			System.out.println(s1 + ">" + s2);
		}else if(s1.compareToIgnoreCase(s2) < 0){
			System.out.println(s1 + "<" + s2);
		}else{
			System.out.println(s1 + "=" + s2);
		}
		//hello=Hello
	}
String类常用方法
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/333339.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号