目录
String使用时的注意事项
阅读程序并解答(1)
阅读程序并解答(2)
String的应用案例
案例1
案例2
小结
String使用时的注意事项
- String对象的内容不可改变,被称为不可变字符串对象。(每次试图改变字符串对象实际上是新产生了新的字符串对象了,变量每次都是指向了新的字符串对象,之前字符串对象的内容确实是没有改变的,因此说String的对象是不可变的。)
- 只要是以 “...” 方式写出的字符串对象,会存储到字符串常量池,且相同内容的字符串只存储一份(这么设计主要是为了节约内存);但通过 new 方式创建字符串对象,每 new 一次都会产生一个新的对象放在堆内存中。
阅读程序并解答(1)
public class Test{
public static void main(String[] args){
String s2 = new String("abc");
String s1 = "abc";
System.out.println(s1 == s2);
}
}
- 两行代码分别创建了几个对象
- 运行结果
第一行代码执行时,new操作原本是让字符存储到了堆内存中,但此时String内部写了"abc",用双引号写出来的字符会被放入字符串常量池中;所以字符串常量池和堆内存中都各自有一个abc字符。
所以第一行代码创建了2个对象。
第二行代码是用双引号书写的字符,将被放到堆内存中的字符串常量池里,但此时已存在abc,故第二行代码没有创建新的对象。
s2的地址指向堆内存的abc,s1的地址指向堆内存中的字符串常量池的abc,所以两者地址并不相等,所以运行结果为false。
阅读程序并解答(2)
public class Test3{
public static void main(String[] args){
String s1 = "abc";
String s2 = "ab";
String s3 = s2 + "c";
System.out.println(s1 == s3);
}
}
public class Test4{
public static void main(String[] args){
String s1 = "abc";
String s2 = "a" + "b" + "c";
System.out.println(s1 == s2);
}
}
判断上面两段程序输出的结果分别是什么
第一段程序:s1指向放在字符串常量池里的abc,s3是由s2字符串加上字符串"c"运算之后得到的新字符串,所以s1与s3的地址并不相同,输出结果为false;
第二段程序:由于Java存在编译优化机制,程序在编译时,"a" + "b" + "c" 会直接转换成"abc",以提高程序的执行性能,所以检测到字符串常量池中原本存在"abc",不会创建新的字符串,s1与s2指向的地址相同,输出结果为true。
String的应用案例
案例1
需求:
统正确的登录名和密码是:Administrator/123456,请在控制台开发一个登录界面,接收用户输入的登录名和密码,判断用户是否登录成功,登录成功后展示::“欢迎进入系统!”,即可停止程序
(注意:要求最多给用户三次登录机会)
步骤:
- 开发登录界面,提示用户通过键盘输入登录名和密码。
- 设计一个登录方法,对用户的登录名和密码进行正确性认证。
- 根据登录方法返回的认证结果,判断用户是否登录成功。
- 使用循环控制登录界面最多显示3次。
package StringTest;
import java.util.Scanner;
public class Test1 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
//1.写一个简陋的登陆界面
for (int i = 0; i < 3; i++) {
System.out.println("请您输入登陆名称:");
String loginName = sc.next();
System.out.println("请您输入登陆密码:");
String passWord = sc.next();
//3.写一个判断账号与密码是否一致的方法 login();
//5.调用方法
boolean rs = login(loginName,passWord);
if(rs){
System.out.println("登陆成功,欢迎进入系统");
break;
}else{
System.out.println("登录名或密码错误,请您重新确认");
}
}
}
public static boolean login(String loginName,String passWord){
String okLoginName = "Administrator";
String okPassWord = "123456";
//4.判断用户是否登陆成功
return okLoginName.equals(loginName) && okPassWord.equals(passWord);
}
}
运行结果:
案例2
需求:
(使用String实现)实现随机产生验证码,验证码的每位可能是数字、大写字母、小写字母。
步骤:
- 设计一个方法,该方法接收一个整型参数,最终要返回对应位数的随机验证码。
- 方法内定义2个字符串变量:1个用来记住生成的验证码,1个用来记住要用到的全部字符。
- 定义for循环控制生成多少位随机字符,每次得到一个字符范围内的随机索引,根据索引提取该字符,把该字符交给code变量连接起来,循环结束后,在循环外返回code即可。
- 主程序中,调用该方法即可得到随机验证码了。
package StringTest;
import java.util.Random;
public class Test2 {
public static void main(String[] args) {
System.out.println(createCode(4));
System.out.println(createCode(6));
}
//1.设计方法返回指定位数的验证码
public static String createCode(int n){
//定义两个变量 一个存储最终产生的验证码 另一个存储所有可能用到的全部字符
String code = "";
String data = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
Random r = new Random();
//3.开始定义循环产生每位随机字符
for (int i = 0; i < n; i++) {
int index = r.nextInt(data.length());
//5.根据索引去全部字符中提取字符
code += data.charAt(index);
}
return code;
}
}
运行结果:
小结
1、字符串的比较使用==比较好吗?为什么?什么时候使用==?
- 不好,对于字符串对象的比较,==比较的是地址,容易出业务bug
- 基本数据类型的变量或者值应该使用==比较。
2、开发中比较字符串推荐使用什么方式比较?
- 使用String提供的equals方法,它只关心字符串内容一样就返回true。
方法名 |
---|
public boolean equals(Object anObject) |
public boolean equalsIgnoreCase(String anotherString) |
END
学习自:黑马程序员——JavaSE课程