java笔记(2):String(1)

参考资料:网易云网课地址 数组

http://study.163.com/course/courseMain.htm?courseId=1455026spa

 

1、String类的两种实例化方法3d

(1)直接赋值 code

public class Test { public static void main(String arg[]) { String str = "hello world"; System.out.println(str); } }

以上代码能够输出str的值,说明str 已被实例化(未实例化会为null)。咱们知道String类并非基本数据类型,然而以上代码并无用new关键字开辟内存空间。htm

(2)利用构造方法实例化:对象

其实在String类里面含有一个构造方法: public String(String str) 在构造里面依然要接收一个本类对象。blog

public class Test { public static void main(String args[]) { String str = new String("Hello World"); System.out.println(str); } }

说明String类有两种形式,你们主观上应该会认为第二种更加的符合规范,由于通常认为类都需使用new关键字来实例化。但实际来讲并非这样的,具体得往下看。内存

2、字符串的比较开发

基本数值均可用“==”判断是否相等,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); } }

输出结果为:

false
false
true

内存图分析以下:

“==”符号比较的时数据的地址数值,由图可知,虽然三个变量内容相同,可是地址值并不相同。

若是真要比较地址所指向的内容,可使用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)); } }

结果为

true
true
true

 

以上经过equals方法实现了内容的比较,故应当注意在比较字符串时应当使用此方法

一道题目:

请解释在字符串相等的判断中“==”与“equals”的区别?

(1)“==”时Java提供的关系运算符,主要功能是进行数值相等判断,若是用在String对象上,表示的是地址数值的比较;

(2)“equals()”是有String提供的一个方法,此方法专门负责进行字符串内容的比较;

3、字符串常量就是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)

 

4、两种实例化方式的区别

下面探讨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) ; } }

结果为:

true
true
true

此时咱们发现,三个比较值都为真,也就是说三个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

 

 

5、总结

String类对象两种实例化方式的区别:

(1)直接赋值:只会开辟一块堆内存空间,而且会自动保存在对象池中供下次使用;

(2)构造方法: 会开辟两块堆内存空间,一块将称为垃圾,而且将不会自动保存在对象池中,可使用intern()方法手工入池。

相关文章
相关标签/搜索