文章目录
String类在所有项目开发之中都会使用到
String类的两种实例化方式
直接赋值
String str="hello";//str是一个对象,那么"hello"就应该保存在堆内存中
System.out.println(str);
这种赋值方式最为常见。但是String本身毕竟是一个类,既然是类,那么里面一定存在构造方法。String类也不例外,String类的其中一种构造方法如下:
public String(String str)
传统方法:
String str=new String("hello");
System.out.println(str);
该方法符合传统做法,使用关键字new进行对象实例化
暂时不需要考虑这两者的区别以及使用,只需要清楚String类现在提供有两种对象实例化的模式。
字符串相等比较
如果现在有两个int类型的变量,判断其相等可以使用“==”完成。
范例:观察数据类型比较
package MyString;
public class equalsTest {
public static void main(String[] args) {
int x=10;
int y=10;
System.out.println(x==y);
String str1="hello";
String str=new String("hello");
System.out.println(str==str1);
}
}
我们的运行结果:
true
false
“==”本身是进行数值比较的,如果现在用于对象比较,那么所比较的就应该是两个对象所保存的内存地址数值比较,而并没有比较对象的内容。
那么要想比较对象的内容,则必须采用String类提供的equals方法。
范例:使用equals方法比较字符串内容:
String str1="hello";
String str=new String("hello");
System.out.println(str.equals(str1));
面试题:请解释String类“==”与“equals”的区别
1、"==":进行的数值比较,比较的是两个字符串对象的内存地址数值
2、”equals()“:可以进行字符串内容的比较
字符串常量是String的匿名对象
在任何语言的底层,都不会提供有直接的字符串类型。现在所谓的字符串只是高级语言提供给用户方便开发的支持而已。在java之中,本身也没有直接提供字符串常量的概念。所以使用""定义的内容本质上来讲都是String的匿名对象。
观察字符串常量
String str1="hello";
String str=new String("hello");
System.out.println("hello".equals(str));
System.out.println(str.equals(str1));
那么在之前出现的"String str=“hello”",本质上就是将一个匿名的String类对象设置有名字,而且匿名对象一定保存在堆内存中。
**小建议:**在以后的开发过程之中,如果要判断用户输入的字符串是否等同于特定字符串,一定要将特定字符串写在前面。
比较方法
String str=null;//假设由用户输入
System.out.println(str.equals("hello"));
在进行接收用户输入数据的时候一定要考虑到用户没有输入的问题,以上面代码为例,用户没有输入的时候,一定会出现"NullPointorException"问题。
任何字符串常量都是String的匿名对象,所以该对象永远不会为null.
String str=null;
System.out.println("Hello".equals(str));//假设由用户输入。
在以后
的工作学习中,我们强烈建议如上写法,将我们的字符串常量写在前面。
String类两种实例化的区别
在第一节已经给出String类的两种实例化操作,在实际开发之中,使用哪一种更好以及彼此之间的区别有哪些呢?
采用直接赋值
package MyString;
public class equalsTest {
public static void main(String[] args) {
String str1="hello";
String str2="hello";
String str3="hello";
System.out.println(str1==str2);
System.out.println(str1==str3);
System.out.println(str2==str3);
}
}
我们的运行结果是:
true
true
true
为什么没有开辟新的堆空间呢?
String类的设计使用了共享设计模式
在JVM底层实际上会自动维护一个对象池(字符串对象池),如果现在采用了直接复制的模式进行String类的对象实例化操作,那么该实例化对象(字符串内容)将自动保存到这个对象池之中。如果下次继续使用直接赋值的模式声明String类对象,此时对象池之中如若有指定内容,将直接引用;如若没有,则开辟新的字符串对象而后将其保存在对象池之中供下次使用。
所谓的对象池就是一个对象数组(目的是减少开销)
采用构造方法
类对象使用构造方法实例化是标准做法,分析如下:
String str=new String("hello");
通过分析可知,如果使用String构造方法就会开辟两块堆内存空间,并且其中一块堆内存空间将称为垃圾空间。除了这一点缺点之外,会对字符串共享产生问题。
观察我们的字符串共享问题:
package MyString;
public class equalsTest {
public static void main(String[] args) {
String str1="hello";
String str2=new String("hello");
String str3=new String("hello").intern();
System.out.println(str1==str2);
System.out.println(str1==str3);
System.out.println(str2==str3);
}
}
我们的运行结果:
false
true
false
我们在这里值得一提的就是我们的在String类中提供的方法入池操作 public String intern();
面试题:请解释String类中的两种对象实例化的区别
1、直接赋值ÿ