String内存模型和Java常用方法
一、String内存模型
1、直接赋值创建string对象内存原理:
StringTable(串池):字符串常量池,用来存储字符串,只能是在直接赋值中使用才会存在串池当中(JDK7前串池是在方法区里面,StringTable(串池)在JDK7版本开始从方法区中挪到了堆内存,但是运行机制没有发生变化)
eg:
首先mian方法进栈,创建变量s1,查看串池里面有没有abc,此时串池内没有,就创建了一个新的abc,然后将地址值赋值给s1;
创建变量s2,等号右边直接赋值,查看串池里面有没有abc,此时,串池里面已经存在abc,就不会创建abc,而是去复用已经存在的abc。
2、小结:
当使用双引号直接赋值时,系统会检查该字符串在串池中是否存在,如果不存在,创建新的,如果存在,就会复用
3、特点:代码简单,节约内存
4、、new关键字创建string对象内存原理
这里以字符数据为例:
首先main方法进栈,执行第一行代码,此时在堆内存当中产生一个char类型的数组,地址值为0011;再把0011赋值给变量chs;创建s1对象,在堆内存创建一个字符数组内容的小空间,地址值为002,再把002赋值给s1;创建s2对象,在堆内存创建一个字符数组内容的小空间,地址值为003,再把003赋值给s2。
注意:每new一次就会开辟一个新的空间,而且地址值都不相同,所以,这种方式创建的字符串不会复用
特点:会浪费内存空间
二、Java常用方法(比较)
1、==号比的是什么?
(1)基本数据类型:
基本数据类型比较的是数据值
(2)引用数据类型:
引用数据类型比较的是地址值
2、字符串比较
3、直接赋值:
创建变量s1,查看串池里面有没有abc,此时串池内没有,就创建了一个新的abc,然后将地址值赋值给s1;
创建变量s2,等号右边直接赋值,查看串池里面有没有abc,此时,串池里面已经存在abc,就不会创建abc,而是去复用已经存在的abc。此时s1和s2指向的是同一个地址值,所以是True
new关键字赋值:
s1记录的是堆里面的地址值,s2记录的是串池中(也是在堆里面)的地址值
4、用字符串比较内容:
字符串比较:
(1)boolean equals方法(要比较的字符串) :完全一样的结果才是true,否则为false
(2)boole equakslgnoreCase(要比较的字符串) :忽略大小写的比较
package com.itheima03.String;
public class StringDemo02 {
public static void main(String[] args) {
//1、创建两个字符串对象
String s1 = new String("abc");
String s2 = "ABc";
//2、==号比较
//引用数据类型:比的是地址值
//基本数据类型:比的是数据值
System.out.println(s1==s2);//false s1记录的是堆里面的地址值,s2记录的是串池里面的地址值
//3、比较字符串对象中的内容是否相等
boolean result = s1.equals(s2);
System.out.println(result);//false
//4、比较字符串对象中的内容是否相等,忽略大小写(忽略大小写,只能是英文状态下的a和A,汉字的大小写无法使用)
boolean result1 = s1.equalsIgnoreCase(s2);
System.out.println(result1);//true
}
}
运行结果:
false
false
true
键盘录入的字符串与赋值的字符串比较:
package com.itheima03.String;
import java.util.Scanner;
public class StringDemo03 {
public static void main(String[] args) {
//从键盘录入一个abc
Scanner sc = new Scanner(System.in);
System.out.println("请输入一个字符串");
String s1 = sc.next();
//代码中再定义一个字符串abc
String s2 = "abc";
//用==后比较S1和S2是否一样
System.out.println(s1==s2);
}
}
运行结果:
请输入一个字符串
abc
false
5、### 注意:
字符串录入的字符串是new出来的,s1与s2的地址值不同,s1是new出来的,是在堆内存里面,而s2直接赋值也是在堆内存里面,但是是在堆内存的串池里面,所以是false
结论:以后只要想比较字符串的内容,就必须使用string里面的方法(equals和equakslgnoreCase)
练习:用户登录
需求:
已知正确的用户名和密码,请用程序实现模拟用户登录,总共给三次机会,登录之后,给出相应的提示
package com.itheima03.String;
import java.util.Scanner;
/*
练习:用户登录
需求:
已知正确的用户名和密码,请用程序实现模拟用户登录,总共给三次机会,登录之后,给出相应的提示
*/
public class StringDemo04 {
public static void main(String[] args) {
//1、定义两个变量记录正确的用户名和密码
String rightName = "张三";
String rightPassword = "123456";
Scanner sc = new Scanner(System.in);
for (int i = 0; i < 3; i++) {
//2、键盘输入用户名和密码
System.out.println("请输入用户名:");
String userName = sc.next();//提示和接受录入的变量一定要在for循环里面
System.out.println("请输入密码:");
String password = sc.next();
//3、比较
if (rightName.equals(userName) && rightPassword.equals(password)) {
System.out.println("登陆成功!");
break;
} else {
if (i == 2) {
System.out.println("账号" + userName + "已被锁定,请联系管理员");
} else {
System.out.println("用户登录失败,用户名或密码有误,您还剩" + (2 - i) + "次机会");
}
}
}
}
}
运行结果:
请输入用户名:
张三
请输入密码:
123
用户登录失败,用户名或密码有误,您还剩2次机会
请输入用户名:
张三
请输入密码:
1234
用户登录失败,用户名或密码有误,您还剩1次机会
请输入用户名:
张三
请输入密码:
12345
账号张三已被锁定,请联系管理员