Java基础——字符串(一)

Java基础:String类

一、String的特性
1)String类:代表字符串。
2)Java 程序中的所有字符串字面值(如 "abc" )都作为此类的实例实现。
3)String是一个final类,代表不可变的字符序列。 
4)字符串是常量,用双引号引起来表示。它们的值在创建之后不能更改。 可以共享
5)String对象的字符内容是存储在一个字符数组value[]中的。

字符串常量池补充
字符串字面常量是存储在字符串常量池中的

jdk1.6-以前  字符串常量池位于方法区的永久代
jdk1.7       字符串常量池位于堆区
jdk1.8+以后  字符串常量池位于方法区的元空间
二、字符串的创建方式
第一种情况
String s="abc"; 

表示,先在栈上创建一个引用s ,它会先去常量池中看有没有 “abc” 这个常量

如果有,则把字符串常量池中"abc"该字符串的地址返回给当签 s 引用。

如果没有,则在常量池中创建 abc

第二种情况
String s=new String("abc");

相当于 String obj=“abc”; String s=new String(obj) ;
经过这个操作以后,内存中有两份数据: 常量池中一份,堆上一份。由于有了 new 这个操作,不管常量池中原来有没有 “abc” ,它都会在堆上创建一份

三、字符串的比较

例1:字符串常量池的使用

1 String s0 = "abc"; 
2 String s1 = "abc"; 
3 System.out.println(s0==s1);   //true 
4  //    s0  和  s1 都指向了常量池中的同一个 "abc"

例2:String中 == 与equals的区别

1 String s0 =new String ("abc");   //new 这个操作,将在堆上产生对象,s0指向了堆
2 String s1 =new String ("abc"); 
3 System.out.println(s0==s1); //false  s0 和 s1 指向的是堆上不同de的对象
4 System.out.println(s0.equals(s1)); //true 因为String类重写了equals方法,比的是实体的内容 

== 和 equals的区别

1 == 既可以比较基本类型也可以比较引用类型。对于基本类型就是比较值,对于引用类型 就是比较内存地址
2 equals的话,它是属于java.lang.Object类里面的方法,如果该方法没有被重写过,默认也是 == ;我们可以看到String等类的equals方法是被重写过的,
而且String类在日常开发中用的比较多,久而久之,形成了equals是比较值的错误观点。 
3 具体要看自定义类里有没有重写Object的equals方法来判断。 
4 通常情况下,重写equals方法,会比较类中的相应属性是否都相等。

例3:编译期确定

1 String s0="helloworld";
2 String s1="helloworld";
3 String s2="hello" + "world";   // 编译的时候,就会完成字面常量的拼接,直接就编译成 helloworld
4 System.out.println( s0==s1 );   //true
5 System.out.println( s0==s2 );   //true

例4:编译期无法确定

1 String s0="helloworld";
2 String s1=new String("helloworld");
3 String s2="hello" + new String("world");
4 System.out.println( s0==s1 ); //false  一个指向常量池,一个指向堆
5 System.out.println( s0==s2 ); //false
6 System.out.println( s1==s2 ); //false

例5 编译期无法确定

1 String s0 = "ab";
2 String s1 = "b";
3 String s2 = "a" + s1;   // s1不是常量,编译期无法确定,
    // 在字符串拼接时,如果出现变量都会在堆内存分配空间,创建对象
4 System.out.println((s0 == s2)); //false

例7:编译期确定 (final)

1 String s0 = "ab";
2 final String s1 = "b";     //加上final 就变成了常量
3 String s2 = "a" + s1;  // 对于两个常量相加,编译器能确定它的值
4 System.out.println((s0 == s2));     //true
四、String类及Integer包装类内存分析
public static void main(String[] args) {    

	//以下两条语句创建了1个对象。"凤山"存储在字符串常量池中    
	String str1 = "凤山";    
	String str2 = "凤山";     
	System.out.println(str1==str2); //true  
   
	//以下两条语句创建了3个对象。"天峨",存储在字符串常量池中,两个new String()对象存储在堆内存中     
	String str3 = new String("天峨");     
	String str4 = new String("天峨");     
	System.out.println(str3==str4); //false    
	  
	//以下两条语句创建了1个对象。9是存储在栈内存中   
	//这里所说的一个对象,是指的9 , i 和 j 则是对9的引用  
	int i = 9;     
	int j = 9;     
	System.out.println(i==j);//true 
	     
	//由于没有了装箱,以下两条语句创建了2个对象。两个1对象存储在堆内存中    
	Integer l1 = new Integer(1);    注意这里是没有装箱操作的
	Integer k1 = new Integer(1);    
	System.out.println(l1==k1);  //false  
	
	 //以下两条语句创建了1个对象。1对象存储在栈内存中。自动装箱时对于 -128-127之间的值,直接使用。   
	 //在Java中会对常用的小范围的数字-128---127之间的数进行缓存 
	Integer l = 20;//装箱     
	Integer k = 20;//装箱     
	System.out.println(l==k); //true    
	
	Integer i1 = 256;     
	Integer i2 = 256;   
	//以下两条语句创建了2个对象。i1,i2变量存储在栈内存中,两个256对象存储在堆内存中,因为对于 -128-127 范围之外的值,会创建新的对象  
	System.out.println(i1==i2);//false  
}
	Integer i = new Integer(1); 
    Integer j = new Integer(1); 
    int z = 1;
    System.out.println(i == j); // false
    System.out.println(i == z); // true
    Integer m = 1; 
    System.out.println(m == i);//  false

1、Integer m=1;java中将1自动装箱成Integer类型,也就是说1已经不是基本数据类型了,变成了对象,也就是引用类型。所以当 m==i 相比较,比较的是地址符,2个对象肯定不相等,所以为false。

2、int z=1;是因为 i 自动拆装为int类型(变成基本类型了)在与z比较,i==z 比较的是数值,所以相等。(一定要记得java的自动装箱 / 拆箱)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值