小标
2018-07-24
来源 :
阅读 1465
评论 0
摘要:本文主要向大家介绍了JAVA语言笔记(2):String(1),通过具体的内容向大家展示,希望对大家学习JAVA语言有所帮助。
本文主要向大家介绍了JAVA语言笔记(2):String(1),通过具体的内容向大家展示,希望对大家学习JAVA语言有所帮助。
一、String类的两种实例化方法
(1)直接赋值
public class Test {
public static void main(String arg[]) {
String str = "hello world";
System.out.println(str);
}
}
以上代码可以输出str的值,说明str 已被实例化(未实例化会为null)。我们知道String类并不是基本数据类型,然而以上代码并没有用new关键字开辟内存空间。
(2)利用构造方法实例化:
其实在String类里面含有一个构造方法: public String(String str) 在构造里面依然要接收一个本类对象。
public class Test {
public static void main(String args[]) {
String str = new String("Hello World");
System.out.println(str);
}
}
说明String类有两种形式,大家主观上应该会认为第二种更加的符合规范,因为一般认为类都需使用new关键字来实例化。但实际来说并不是这样的,具体得往下看。
二、字符串的比较
基本数值都可用“==”判断是否相等,String也可以用“==”进行比较
public class B {
public static void main(String[] args) {
String stra = "Hello";
String strb = new String("Hello");
String strc = strb;//引用传递
System.out.println(stra == strb);
System.out.println(stra == strc);
System.out.println(strb == strc);
}
}
输出结果为:
falsefalsetrue
内存图分析如下:
“==”符号比较的时数据的地址数值,由图可知,虽然三个变量内容相同,但是地址值并不相同。
如果真要比较地址所指向的内容,可以使用String类里面提供的方法 public boolean equals;
public class B {
public static void main(String[] args) {
String stra = "Hello";
String strb = new String("Hello");
String strc = strb;//引用传递 System.out.println(stra.equals(strb));
System.out.println(stra.equals(strc));
System.out.println(strb.equals(strc));
}
}
结果为
truetruetrue
以上通过equals方法实现了内容的比较,故应当注意在比较字符串时应当使用此方法
一道题目:
请解释在字符串相等的判断中“==”与“equals”的区别?
(1)“==”时Java提供的关系运算符,主要功能是进行数值相等判断,如果用在String对象上,表示的是地址数值的比较;
(2)“equals()”是有String提供的一个方法,此方法专门负责进行字符串内容的比较;
三、字符串常量就是String的匿名对象
实际上任何语言都没有提供字符串这一概念,很多语言使用字符数组来描述。Java里也没有字符串这一基本数据类型,而是通过String类的匿名对象来实现。
例:观察字符串是匿名对象
public class B {
public static void main(String[] args) {
String stra = "Hello";
System.out.println("Hello".equals(stra));
}
}
匿名对象能够调用方法,故说明字符串为一个匿名对象
所谓的直接赋值相当于 将一个对象设置了一个名字,但唯一的区别是,String类的匿名对象是由系统自动生成的,并不是由用户直接定义。
开发小技巧:
为了避免出现空指向异常,可将字符串写在前面调用方法
String input = //由用户输入
input。equals("hello")
以上代码input由用户输入赋值,如果用户没有输入则为空,那么就会出现空指向异常。
为了尽量避免这一情况发生,可将其倒置
String input = //由用户输入
“hello”.equals(input)
四、两种实例化方式的区别
下面探讨String类两种实例化方式的区别
1.直接赋值
直接赋值就是将一个字符串的匿名对象设置一个名字
String str = "Hello";
此时在内存中会开辟一块堆内存,并且由一块栈内存指向该堆内存
我们接着分析以下代码:
public class Test {
public static void main(String args[] ) {
String stra = "hello" ;
String strb = "hello" ;
String strc = "hello" ;
System.out.println(stra == strb) ;
System.out.println(stra == strc) ;
System.out.println(strb == strc) ;
}
}
结果为:
truetruetrue
此时我们发现,三个比较值都为真,也就是说三个String对象地址值相等(即三个变量名stra,strb,strc指向同一堆内存,为同一个对象)。
要想解释以上结果,需引入共享模式的概念:
在JVM的底层存在有一个对象池(不一定只保存String对象),如果用直接赋值的方式进行String对象的实例化,会将该实例化对象(字符串)入池保存,如果下次继续使用直接复制方式声明String对象,并且设置了同样的内容(字符串值),那么将直接进行引用,不会开辟新的堆内存空间。(所谓的对象池就是一个对象数组)。
2.构造方法
构造方法即使用new关键字
String str = new String("hello");
内存图分析
可以发现,如果使用构造方法将会开辟两块堆内存空间,并且其中一块堆内存空间将变成垃圾空间。另外还会对字符串共享产生问题。
public class Test {
public static void main(String args[] ) {
String stra = new String("hello") ;
String strb = "hello" ;
System.out.println(stra == strb) ;
}
}
结果为
false
如果使用了构造方法其内容并不会保存在内存池之中。
如果希望存入内存池,需手工使用intern()方法
public class Test {
public static void main(String args[] ) {
String stra = new String("hello") .intern();
String strb = "hello" ;
System.out.println(stra == strb) ;
}
}
结果为
true
五、总结
String类对象两种实例化方式的区别:
(1)直接赋值:只会开辟一块堆内存空间,并且会自动保存在对象池中供下次使用;
(2)构造方法: 会开辟两块堆内存空间,一块将称为垃圾,并且将不会自动保存在对象池中,可以使用intern()方法手工入池。
希望对JAVA有兴趣的朋友有所帮助。了解更多内容,请关注职坐标编程语言JAVA频道!
喜欢 | 1
不喜欢 | 0
您输入的评论内容中包含违禁敏感词
我知道了

请输入正确的手机号码
请输入正确的验证码
您今天的短信下发次数太多了,明天再试试吧!
我们会在第一时间安排职业规划师联系您!
您也可以联系我们的职业规划师咨询:
版权所有 职坐标-一站式AI+学习就业服务平台 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
沪公网安备 31011502005948号