详解java String类型(一)

关于String类型,我们对它是既熟悉又陌生,它可讲的地方还真是不少.众所周知,String类型算是Java 的一个难点,确实,刚开始我也是听困惑,也没觉得,不就是一个字符串吗?有什么好学的?于是就没怎么管.一直对它是模模糊糊的概念,就以为他是表示一个字符串,直到有一天看见了一篇关于讲解Java String类型的文章,突然觉得这东西还要那么多可以研究的地方.
下面进入正题,讲讲关于String 困惑大家的地方吧.
1.首先要明确一点,String不属于8个基本类型的数据,而是一个对象.
2.既然String是对象,就要说说怎么创建,
String str = new String("hello java");  //这是创建了一个String类型的对象,
String str2 = "hello java";             //这也可以啊,而且平时我们都是这么写的
那他们有什么区别呢?说到这里,就要说说String特有的String池了(StringPool),对于直接通过赋值创建的对象,他们都会被放在StringPool中,并且每次创建的时候,都会去StringPool中看看有没有相同的对象,有的话就将新创建对象的引用指向该对象,没有的话就对新创建这个对象,而用new 方法创建的对象,则不会放在StringPool中,而是放在堆内存中,不管有没有相同的对象,都回去重新创建一个新的对象,但是这是很耗内存的,虽然那点内存并不影响什么,但是还是不提倡这么使用.下面举个例子:
String a1 = "hello java";//执行这条语句的时候,会首先到StringPool中查找有没有"hello java"的的对象,发现没有,则会创建一个新的对象并放在StringPool中.a1则会指向该对象

String a2 = "hello java";//看看这行代码会干什么,先到StringPool中查找"hello java",发现有这个对象(上一行代码),然后a2就指向了找到的对象的引用.

再来看看new方法产生对象又是怎么的:

String a3 = new String("hello java");//执行这行代码使,这不会去找Stringpool中有无该对象,而是直接在堆内存中创建对象,并且不管堆内存有无该对象,直接创建

String a4 = new String("hello java");//这也就同理了

那我们来测试一下:

System.out.println("a1 == a2 ?"+(a1 == a2)); //运行结果为true a1,a2指向同一个对象

System.out.println("a3 == a4 ?"+(a3 == a4));//运行结果为false,a3,a4表示两个不同的对象,虽然值一样


3.下面我们来看看关于字符串的"==" 和 equals()

都知道"=="是用来判断两个对象是否相等,那么问题来了什么才算是相等呢?来看一个例子:

String a1 = "hello java";
		String a2 = new String("hello java");
		String a3 = a1;
		
		System.out.println("比较   ==  --------------------");
		System.out.println(a1 == a2);
		System.out.println(a1 == a3);
		System.out.println(a2 == a3);

看的出运行结果吗?

运行发现结果是:

比较   ==  --------------------
false
true
false

其实结果你也可能看出来了?a1和a3指向同一个对象,所以结果为true.a1和a2分别指向了不同的对象,但是值是一样的为什么为false."=="到底比较的是什么,其实"=="比较的就是内存地址值,由于指向了不同的对象,所以所指向的对象的内存地址值当然不同.

equals方法又比较的是什么呢:

String a1 = "hello java";
		String a2 = new String("hello java");
		String a3 = a1;
		
		System.out.println("比较   equals  --------------------");
		System.out.println(a1.equals(a2));
		System.out.println(a1.equals(a3));
		System.out.println(a2.equals(a3));

运行结果如下:

比较   equals  --------------------
true
true
true

查看API ,String是继承于Object类的,而Object类的equals()方法也是比较的对象是否相等,那就奇怪了这不和"=="作用相同吗,那结果怎么不一样啊,继续查看API,发现String类的equals方法定义如下:



String类中equals变成比较对象的值是否相同,而"=="比较的是内存地址值是否相同,那这里很多人就晕了,内存地址值我怎么知道是多少,其实Object类有一个hashcode()方法就是通过将该对象的内部地址转换成一个整数来实现的.Object原始的equals()方法用来比较两个对象的地址值,而原始的hashCode()方法用来返回其所在对象的物理地址.这里也就有点明白了吧,equals()方法其实依赖于hashcode()方法的返回值.而String类有重写了hashcode()方法:


String a1 = "hello java";
		String a2 = new String("hello java");
		String a3 = a1;
		System.out.println("hashcode-----------------------");
		System.out.println(a1.hashCode());
		System.out.println(a2.hashCode());
		System.out.println(a3.hashCode());

运行结果:

hashcode-----------------------

-1605094224
-1605094224
-1605094224

原来String类的哈希值是通过字符串计算出来的,那也就不奇怪了,对象不同,但是他们的字符串的内容相同,当然hashcode值也就相同,equals()方法当然会返回true.记住:"==" 比较的内存地址值,只要指向的不是同一个对象,就不相等,而equals()方法则是比较内容是否相等(针对String类).



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值