Java | 您所在的位置:网站首页 › java中的实例对象是什么 › Java |
1、String类的两种实例化方式 String类不是一个基本数据类型,它是一个类,这个类设计过程种加入了Java的特殊支持,其实例化形式有两种形式: 直接赋值: String 对象 = “内容”;构造方法:public String (String s);以上两种方式均可用,但是具体还是有一些区别。 2、字符串比较对于int类型数据,两个直接赋值的变量使用“ ==”可以进行想等判断,但是对于String类型数据却不能这样直接比较,见如下范例: 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。实际上这里的比较 实际上比较的是两个对象(任意的引用类型)的堆内存的地址数值,属于数值内容的比较,并非堆内存种保存内容的比较。 若要对两个字符串进行比较,可以使用String类中的一个方法:public boolean equals(String str)。 String stra = "hello"; String strb = new String("hello"); String strc = strb; //引用传递 System.out.println(stra.equals(strb)); //true System.out.println(strb.equals(strc)); //true System.out.println(stra.equals(strc)); //true【经典问题】String 比较中 == 与equals的区别? "=="是关系运算符,可以进行数值比较,如果用在String上,表示对象内存地址数值比较,不能比较内容。equals是String类自己定义的方法,用于进行字符串内容的比较。3、String匿名对象任何编程语言都不会提供字符串数据类型,字符串在很多语言中使用字符数组,Java中为解决这个问题,提供了String类,Java里面也提供双引号声明的数据,这些数据不是普通的变量,而是属于String类的匿名对象。 【举例】:验证匿名对象 String str = "hello"; System.out.printlin("hello".equals(str)); //true开发中,在比较字符串内容是否相同时,一般将常量写在前面,这样避免equals前面的字符串内容为null,equals方法本身具有null判断的功能。 4、String类两种实例化的区别由第一节中 的内容可知,对于String示例化方式有两种,到底该使用哪种,两种的区别是什么? 1)分析String类对象直接示例化的形式 【直接赋值】使用 的是最多的: String str = "hello"; System.out.println(str);开辟一块堆内存空间,且一块栈内存直接指向该堆内存空间。 【继续观察直接赋值】 String stra = "hello"; String strb = "hello"; String strc = "nihao"; System.out.println(stra==strb); //true System.out.println(strb==strc); //false System.out.println(stra==strc); //false很奇怪,是不是和前面分析的不太一样,其实还是一样的,只不过有一点需要注意,stra和strb指向的内容是相同的,不会重复开辟堆内存空间。这里涉及到对象池的概念。 关于对象池(Object Pool):Java设计过程中,为方便用户开发,针对几个特殊的类使用了共享设计的思路,String就属于其中一个类,这种设计思路是Java自己的支持,只针对于直接赋值的情况。 在使用直接赋值实例化String类对象操作中,字符串内容定义后实际上会自动保存在一个对象池之中,而后,若有其他 的字符串对象也采用直接赋值的形式,且内容与之前的完全相同,则不会开辟新的堆内存空间,而是通过对象池,找到已有的堆内存空间地址,直接引用,所以会出现如上范例的结果。 1)利用构造方法实例化对象 String str = new String("hello"); System.out.println(str);由以上内存分析可以发现,通过构造方法进行实例化对象操作,最终会产生两块堆内存,其中一块是垃圾空间。 【举例】:没有入池的问题 String stra = new String("hello"); //构造方法 String strb = "hello"; //直接赋值 System.out.println(str);//false使用构造方法进行String类对象实例化,产生的对象不会保存在对象池中,此对象无法重用。若用户需要让这个对象入池,只能通过手工入池方法完成: 手工入池:public String intern(). String stra = new String("hello").intern; //构造方法 String strb = "hello"; //直接赋值 System.out.println(str);//此处结果为true【经典问题】:String类两种对象的实例化区别是什么? 直接赋值(String str ="字符串"):仅开辟一块堆内存空间,且对象可以自动入池以共其他对象重复使用;构造方法(String str = new String("字符串")):开辟两块堆内存空间,且有一块会成为垃圾,产生的对象不会自动入池,需要使用intern()方法手动入池。5、字符串声明后不可改变【举例】: String str = "Hello "; str += "World "; str = str+ "!!!"; System.out.println(str); //Hello World !!!进行内存分析可以发现,以上程序操作都是String类对象的引用发生改变,而字符串的内容实质上根本没有发生改变,这样操作形成了很多垃圾空间,因此,在开发中,一定禁止循环修改String。后续会讲到StringBuffer和StringBuilder,可以用于循环修改。 6、结论1)String开发中都使用直接赋值,并且不要频繁修改,因为会产生垃圾空间;2)字符串内容比较时用equals()方法。 |
CopyRight 2018-2019 实验室设备网 版权所有 |