首页 > 系统相关 >String内存模型和Java常用方法

String内存模型和Java常用方法

时间:2023-07-09 14:44:44浏览次数:43  
标签:abc Java String s2 s1 串池 内存 字符串

一、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
账号张三已被锁定,请联系管理员

标签:abc,Java,String,s2,s1,串池,内存,字符串
From: https://www.cnblogs.com/xiao-xiao1024/p/17538718.html

相关文章

  • 面试类-Java基础 (三)
    String是Java基本数据类型吗?可以被继承吗?String是Java基本数据类型吗?不是。Java中的基本数据类型只有8个:byte、short、int、long、float、double、char、boolean;除了基本类型(primitivetype),剩下的都是引用类型(referencetype)。String是一个比较特殊的引用数据类型......
  • 【java】虚拟机的内存划分
    为了提高运算效率,就对空间进行了不同区域的划分,因为每一片区域都有特定的处理数据方式和内存管理方式。  区域名称作用程序计数器程序计数器是CPU中的寄存器,它包含每一个线程下一条要执行的指令的地址本地方法栈当程序中调用了native的本地方法时,本地方法执行......
  • 【java】输入输出
    输出换行输出语句:输出内容后进行换行,格式如下:System.out.println(输出内容);//输出内容之后,紧接着换行不换行输出语句:输出内容后不换行,格式如下System.out.print(输出内容);////输出内容之后不换行 示例代码:publicclassTestPrintlnAndPrint{publicstaticvoid......
  • 记录一个打印内存的日志函数
    在调试代码的时候,经常需要dump一段内存,有时候不得不自己动手写一个函数。现在先记录一个简单版本的内存打印函数。constchar*hexstr="0123456789ABCDEF";voiddump(intlevel,constchar*tag,constuint8_t*data,uint32_tlength){#define_CNT_PER_LINE(1<<4)......
  • 【java】数据类型
    Java的数据类型分为两大类:基本数据类型:包括整数、浮点数、字符、布尔。引用数据类型:包括数组、类、接口、枚举、注解。   自动类型转换(1)当把存储范围小的值(常量值、变量的值、表达式计算的结果值)赋值给了存储范围大的变量时。inti='A';//char自动升级为int,其......
  • java日志框架
    发展简图历程:使用logback+slf4j进行日志框架处理,出自一人之手,衔接更好! logback官网手册(英文):https://logback.qos.ch/manual/index.htmllogback中文手册:http://www.logback.cn/博客中文手册:https://blog.csdn.net/qq_26462567/article/details/115757354 ......
  • 【java】源文件和类
    (1)源文件名是否必须与类名一致?public呢?如果这个类不是public,那么源文件名可以和类名不一致。但是不便于代码维护。如果这个类是public,那么要求源文件名必须与类名一致。否则编译报错。我们建议大家,不管是否是public,都与源文件名保持一致,而且一个源文件尽量只写一个类,目的是为......
  • JavaScript 模块
    JavaScript模块 一般来讲,模块是一个独立的JavaScript文件 模块文件可以包含一个类定义、一组相关的类、一个实用函数库或者是一些待执行的代码 以模块的形式编写代码,任何符合模块编码形式JavaScript代码段,都可当做一个模块JavaScript中未定义支持模块的语言结构,所以......
  • Java扩展Nginx之一:你好,nginx-clojure
    欢迎访问我的GitHub这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos关于Nginx扩展以欣宸自己为例,对一个java程序员来说,nginx并不陌生,下图应该是最常见的使用场景了,反向代理:除了反向代理,nginx的模块化机制让nginx具备了更多丰富的特性,例......
  • Object.equals 和 String.equals的区别
    一. 源码展示:1.Object.equals:①引用类型地址值比较,直接返回结果:true||falsepublicclassObject{publicbooleanequals(Objectobj){return(this==obj);}} 2.String.equals:①判断地址值是否相等,若相等返回true,若不......