1、8String类对象的两种实例化方式1、 课程名称:String对象的两种实例化方式2、知识点2.1、上次课程的主要知识点数组2.2、本次预计讲解的知识点1、String类的两种实例化方式的区别;2、String类对象的比较;3、String 对象的使用分析;3、具体内容( )3.1、String类的两种实例方式String并不是一个基本数据类型,它本身属于一个类, 但是这个类在设计的过程之中加入了一些java自己的特殊支持。所以对于这类对象实例化方式就有两种形式: 直接赋值:String 对象 = “内容”; 构造方法:public String(String s);范例:使用直接赋值pub
2、lic class StringDemo public static void main(String args) String str = Hello; str = str + World; System.out.println(str); 范例:利用构造方法public class StringDemo public static void main(String args) String str = new String(Hello); str = str + World; System.out.println(str); 至少现在通过执行结果来讲,String 类的两种实例化方式都是
3、可用的。3.2、String 的相等比较如果现在有两个int型的变量,那么要进行相等的判断,则直接使用”=”即可;范例:两个int比较public class StringDemo public static void main(String args) int x = 10;/直接赋值 int y =10; /直接赋值 System.out.println(x=y);/true 发现两个利用直接赋值实现的程序,那么使用”=”的时候可以进行正常的进行相等判断。但是如果现在将同样的的操作形式用在string上呢?范例:观察string的比较public class StringDemo publ
4、ic static void main(String args) String stra = hello; String strb = new String(hello); String strc = strb; /引用传递 System.out.println(stra=strb);/false System.out.println(strb=strc);/true System.out.println(stra=strc);/false 通过现在的执行可以发现一个非常严重的问题,此时字符串的内容实际上都是相同的,而在使用”=”比较之后我们发现有的比较结果是false,那么为什么呢?所以如果
5、在程序中如果使用“=”比较的只是两个对象(任意的引用类型)堆内存地址数值 ,属于数值内容的比较,并不是堆内存保存内容的比较,那么要想进行string对象内容的比较则可以利用string类中提供的方法来完成: 字符串比较(暂时将此方法进行修改)public Boolean equals (String str);范例:利用equals()实现字符串内容的比较。public class StringDemo public static void main(String args) String stra = hello; String strb = new String(hello); Strin
6、g strc = strb; /引用传递 System.out.println(stra.equals(strb);/true System.out.println(strb.equals(strc);/true System.out.println(stra.equals(strc);/true 由于内容是可控因素,而地址是不可控因素,所以在日后开发之中,只要是字符串的比较都使用.equals()方法来完成,绝对不可能出现”=”。面试题:请解释在string比较中”=”与 equals()的区别? “=”:是java本身提供的关系运算符,可以进行数值比较,如果用在String上表示对象内存地
7、址数值比较。 “equals()”:是String类自己定义的方法,用于字符串内容的比较。3.3、String匿名对象任何的编程语言都不会提供有字符串这一数据类型。字符串的描述在很多语言之中都使用字符数组表示。而java的设计之初为了解决这样的一个问题,专门提供了一个Sting类来进行描述。但是随着发展,为了能够让程序变得更加的好易于开发,所以在java里面也提供双引号的声明的数据,而这些数据,在java中并不是普通的变量,而属于String类的匿名对象。范例:验证匿名对象public class StringDemo public static void main(String args)
8、String str = hello; System.out.println(hello.equals(str); 现在发现,此时已经可以通过字符串调用equals()方法,那么就证明一点,字符串的确是String类的匿名对象。那么之前的”String 字符串对象 =”字符串”;”,本质就是为一个字符串的匿名对象起了一个名字。微有作用的经验分享:如果现在假设你的开发有这样一种需求:用户输入 一些指令,而后根据输入指令判断要 执行的操作。那么此时就存有两种做法:做法一:利用String变量调用equals()方法public class StringDemo public static void
9、 main(String args) String input =run;/假设为输入数据 if(input.equals(run) System.out.println(*系统开始运转*) 但是,既然input的内容是由用户输入的,那么就有可能不输入。如果不输入内容就有能为 null,则null调用equals()这个方法就有能出现错误(NullPointerException)。做法二:反过来写public class StringDemo public static void main(String args) String input =null;/假设为输入数据 if(run.equ
10、als(input) System.out.println(*系统开始运转*); 首先字符串的匿名对象永远不可能是null,并且在equals()方法里面支持有null的验证,所以如果发现要比较的内容为null返回的 就是false.字符串常量 = String类的匿名对象。比较字符串内容是否相同时,将常量写在前面。3.4、String类两种实例化对象的区别(核心)声明: 在开发之中如果发现,有多种方式可以实现同一结果,那么就有可能出现面试题。此时对 于String类的实例方式出现两种,那么这两种方式到底该使用那一种,以及每种方式的区别是什么呢?分析一:分析String类对象直接实例化的 形式
11、直接赋值是现在为此看见最多的:String str=”hello”;public class StringDemo public static void main(String args) String str = hello; System.out.println(str); 开辟一块堆内存空间,并且一个栈内存将直接指向该堆内存空间。范例:继续观察直接赋值public class StringDemo public static void main(String args) String stra = hello; String strb = hello; String strc = nih
12、ao; System.out.println(stra=strb);/true System.out.println(stra=strc);/false System.out.println(strb=strc);/fasle 本程序的内存关系图如下:解释:关于对象池的概念(Object Pool)在java设计过程之中为了方便用户的代码编写开发,针对于几个特殊的类使用了共享设计的思路,其中String就属于这其中的一员 。这种 设计思路是java自己的支持,而且只针对直接赋值的情况。在使用直接赋值实例化String类对象操作之中,字符串的内容定义之后实例上会自动将其保存在一 个对象池之中,而
13、后如果现在有其 他的字符串对象也采用了直接赋值的形式,并且内容与之前的字符串内容完全相同,那么不会开辟新的堆内存空间,而是通过对象池找到已有的堆内存空间地址,直接引用即可,所以就会造成若干个字符串直接赋值之后,当内容相同时,地址是完全相同的,所以”=”的结果也是相同的,这样的设计就是共享设计模式,分析二:利用构造方法实例化对象还是以下面的程序为分析依据:public class StringDemo public static void main(String args) String str = new String(hello); System.out.println(str); 看内存关
14、系。通过此时的内存分析可以发现 ,如果采用了构造方法进行string类对象的实例化操作,那么最终将产生两块堆内存,其中有一块是垃圾空间。如果现在使用了构造方法进行string类对象实例化还会牵扯到入池的问题,范例:没入池 public class StringDemo public static void main(String args) String stra = new String(hello);/构造方法 String strb = hello;/直接赋值 System.out.println(stra=strb);/false 现在的代码之中,发现如果使用构造方法进行String类
15、对象实例化,那么所产生的对象不会保存在对象池之中,也就是说此对象无法重用。如果现在用户需要让这个对象入池,则只能通地手工的方式完成: 手工入池:public String interm().范例:手工入池public class StringDemo public static void main(String args) String stra = new String(hello).intern();/构造方法 String strb = hello;/直接赋值 System.out.println(stra=strb);/true 面试题:请解释string类两种对象的 实例化区别? 直
16、接赋值(String str= “字符串”;):只会开辟 一块堆内存空间,并且对象可以自动入池以供其它对象重复使用。 构造方法(string str = new String(“字符串”):会开辟两块堆内存空间,并且有一块堆内存将成为垃圾,同时产生的实例化对象不会直接入池,需要intern()方法手工入池。3.5、字符串声明则不可改变好像之前学习过一个”+”,利用这一概念可以实现字符串改变。范例:分析一下代码public class StringDemo public static void main(String args) String str = Hello ; str +=World;
17、 str = str+!; System.out.println(str);/HelloWorld! 于是就根据以上的程序来进行内存分析。可以发现整个操作流程之中,都是String类对象的 引用发生着改变,而字符串的内容没有改变,这样操作会形成垃圾,正因为如此,所以在实际开发中,以下的操作禁止出现。范例:循环修改Stringpublic class StringDemo public static void main(String args) String str = ; for(int x=0;x1000;x+) str +=x; System.out.println(str);/HelloWorld! 这种代码会”重新改变引用”1000次,并且会大量产生垃圾,也就是说String 不适合于频繁修改,4、总结1、string开发中都使用直接赋值,并且不要频繁修改; 2、字符串内容比较时使用equals()方法;
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1