package Main; import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); String str1 = sc.next(); System.out.println("str1 = " + str1); String GetChar = sc.nextLine(); System.out.println("只是为了读取回车,处理缓冲区!"); String str2 = sc.nextLine(); System.out.println("A line String str2 = " + str2); String str3 = "Hello World"; System.out.println("Static String str3 = " + str3); String str4 = new String("Hello World"); System.out.println("String str4 = " + str4); sc.close(); } }
首先讲讲从键盘输入获取字符串!一般的next();方法是读取到空格或者回车标识读入的结束,而从空格或者回车开始,到键盘键入的全部结束(包括回车)都会放入缓冲区,这说明Scanner扫描线读入是和C语言的scanf();标准输入是一样的,并不是c++的IO流输入!
如何解决这个缓冲区的问题呢?
加入一个String类型的变量,专门读取缓冲区即可!可见上面的代码。
我们知道,静态初始化就是把一个字符串赋值给String对象,但是这个赋值是如何进行的呢?实际上就是把String的对象(比如strObj)作为String类的引用,说白了就是这个对象实际上是栈区的一个数,它的含义是对象的首地址,也就是引用。原本一个静态字符串有它自己的存储空间,也就是一块在堆区的空间,也有它既定的首地址,假设:
静态字符串:“Hello World” -----> Init = 0x0000
静态初始化StrObj = “Hello World” -----> StrObj = 0x0000
这样的坏处是StrObj 和 Init都指向了同一处地址,这是很危险的,一旦一个变量被垃圾回收了,那么另一个对象很可能会再次被访问,但是这样的访问是不允许的!是导致空指针异常的一个可能原因!
String str = new String(“Hello World”);
生成匿名对象:Init = 0x0000 -----> Init = “Hello World”
调用拷贝构造函数(底层):str = 0x0011 -----> str = “Hello World”
这样就不会造成上述说的空指针异常的问题了,其实还有别的问题!我们在进行String类的对象的比较的时候,比较的是他们的地址!!!
这就是我们后面要简述的字符串比较的问题!
package Main; import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); String str1 = sc.nextLine(); String str2 = "Hello World"; String str3 = new String("Hello World"); System.out.println(str1 == str2); System.out.println(str1 == str3); System.out.println(str2 == str3); sc.close(); } }
这是为什么呢?根据我们上面的讲述,可以知道String的对象其实就是引用,所以我们在对对象进行比较的时候,其实就是在比较他们的地址,很明显这些地址都是不相同的(有什么疑问私信我)
那么用什么方法呢?
package Main; import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); String str1 = sc.nextLine(); String str2 = "Hello World"; String str3 = new String("Hello World"); System.out.println(str1.compareTo(str2)); System.out.println(str1.compareTo(str3)); System.out.println(str2.compareTo(str3)); sc.close(); } }
其实这个 对象.compareTo(被比较的对象);
和C语言的strcmp(str1, str2);是一模一样的,是返回俩字符串的差值(0/1/-1)!
很明显,如果俩字符串相同,那就返回0,前面那个对像小,就返回-1,否则返回1……
所以我们今天就深度地从对象实例化、引用、拷贝构造的角度分析和掌握了String对象的不同实例化方式之间的区别,以及大小比较的方式方法!