Connor学Java - Day06

在这里插入图片描述

Learn && Live
虚度年华浮萍于世,勤学善思至死不渝

前言

Hey,欢迎阅读Connor学Java系列,这个系列记录了我的Java基础知识学习、复盘过程,欢迎各位大佬阅读斧正!原创不易,转载请注明出处:http://t.csdn.cn/jVH6W,话不多说我们马上开始!

1.字节和字符的区别?

字节:存储容量的基本单位,1字节 = 8个二进制位

字符:数字、字母、汉字以及其它语言的各种符号,一个字符由一个字节或多个字节的二进制单位组成,Java中,字符型数据(char)的大小为2个字节,16位,简单来记就是一个char = 一个汉字

2.String类的特性?

public final class String implements java.io.Serializable, 
                          Comparable<String>, CharSequence {
	private final char value[];  // JDK9之后为byte[]
	private int hash;
	......
}

(1)final类,不能被继承

(2)实现了Serializable和Comparable接口,支持序列化和比较

(3)底层通过char[]实现(JDK9之后为byte[]),被final修饰,因此String对象创建后不可被修改,具有不可变性

3.String为什么要设计为不可变类?

这个问题可以考虑从两个大的方面回答:性能优化和安全性
在这里插入图片描述

4.String的不可变性?

通过字面量方式为字符串赋值时,此时的字符串存储在方法区的字符串常量池中,并且在字符串常量池中不会存储相同内容的字符串。

String s1 = "hi";
String s2 = "hi";
s1 = "hello";

刚开始字符串s1和s2内容相等,都指向字符串常量池中的同一个地址,如下图所示:

在这里插入图片描述
当s1值的改变之后,此时s2的值不变还是指向原来的内存地址,但是s1会重新分配内存地址进行赋值,如下图所示:

在这里插入图片描述
总结1:String字符串具有不可变性,当字符串重新赋值时,不会在原来的内存地址进行修改,而是重新分配新的内存地址进行赋值。

String s3 = "abc";
String s4 = s3 + "def";
System.out.println(s3); //abc

总结2:当字符串进行拼接时,也不会在原来的内存地址进行修改,而是重新分配新的内存地址进行赋值。

String s5 = "abcd";
String s6 = s5.replace("d", "g");
System.out.println(s5);

此时的内存结构如下图所示:

在这里插入图片描述
总结3:当调用String的replace方法修改指定的字符或字符串时,也不会在原来的内存地址进行修改,也是重新分配新的内存地址进行赋值。

5.String str = “i” 与 String str = new String(“i”)一样吗?

不一样

通过字面量方式为字符串赋值时,此时的字符串存储在方法区的字符串常量池中;
通过new+构造器方式实例化字符串时,字符串对象存储在堆中,但是字符串的值仍然存储在方法区的常量池中。如下图所示:

在这里插入图片描述

// 通过字面量方式为字符串赋值时,此时字符串存储在方法区的字符串常量池中
String s1 = "hello";
String s2 = "hello";

// 通过new+构造器方式实例化字符串时,字符串对象存储在堆中
String s3 = new String("hello");
String s4 = new String("hello");

System.out.println(s1 == s2); // true
System.out.println(s1 == s3); // false
System.out.println(s1 == s4); // false
System.out.println(s3 == s4); // false
public class Person {
    public String name;
    public int age;
    Person() {}
    Person(String name,int age) {
        this.name = name;
        this.age = age;
    }
}
public static void main(String[] args) {
    Person p1 = new Person("Tom", 18);
    Person p2 = new Person("Tom", 18);
    System.out.println(p1.name == p2.name); // true
}

此时的内存结构如下图所示:

在这里插入图片描述
如果p2中name值进行了修改,那么就会在字符串常量池中新生成一个修改后的值,然后改变堆中name指向的地址值,内存结构就会变成如下图所示:

在这里插入图片描述

6.String str = new String(“i”)一共创建了几个对象?

一共会创建两个对象,一个是使用new创建的对象,存储在堆中;另一个是常量对象"i",存储在字符串常量池中

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ConnorYan

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值