Java之 字符串String、数据类型转换

(一)字符串String

1,string的创建方式

  • 方式一
 String str = "Java";
  • 方式二
 String str =new String("Java");
  • 两种方式的区别: String 创建的字符串存储在公共池中,而 new 创建的字符串对象在堆上
  • 示例:
String s1 = "Java";              // String 直接创建
String s2 = "Java";              // String 直接创建
String s3 = s1;                    // 相同引用
String s4 = new String("Java");   // String 对象创建
String s5 = new String("Java");   // String 对象创建

s1 == s2 ==s3  = true 比较的是内存地址
s3 == s4 == s5  = false  不同对象,地址不同(String对象的不可变性)

equals方法比较  都返回 true  因为String的equals方法的重写,比较的是堆中的值。
  

2,string的不可变性

1)不可变的原因

String是private final 初始化之后不可改变

public static void main(String[] args) {
    String s = "ABCDEF";
    System.out.println("s = " + s);
    
    s = "123456";
    System.out.println("s = " + s);
}

输出:

s = ABCDEF
s = 123456
  • 解析:创建String对象的时候,s指向的是内存中的"ABDCEF",当执行语句s = “123456"后,其实又创建了一个新的对象"123456”,而s重新指向了这个新的对象,同时原来的"ABCDEF"并没有发生改变,仍保存在内存中。

  • 有办法改变吗? 通过反射修改

public static void reflectString() throws Exception{
    
    String s = "ABCDEF";
    System.out.println("s = " + s);
    
    Field valueField = s.getClass().getDeclaredField("value");
    valueField.setAccessible(true);
    
    char[] value = (char[]) valueField.get(s);
    value[0] = 'a';
    value[2] = 'c';
    value[4] = 'e';
    
    System.out.println("s = " + s);
}

输出:

s = ABCDEF
s = aBcDeF

3,String,StringBuffer与StringBuilder区别

  • 1,String:字符串常量,字符串长度不可变
  • 2,StringBuffer:字符串变量(Synchronized,即线程安全)
  • 3,StringBuilder:字符串变量(非线程安全)
  • 区别
    在这里插入图片描述

(二)基本数据类型与封装类型

1,基本数据类型

在这里插入图片描述

2,自动装箱和拆箱

1,什么是装箱,拆箱
  • 装箱就是 自动将基本数据类型转换为包装器类型;
  • 拆箱就是 自动将包装器类型转换为基本数据类型
Integer i = 10;  //装箱
int n = i;   //拆箱
2,自动拆箱和装箱原理
  • 装箱原理
    基本数据类型–>封装类 (装箱)
Integer i = 10;
实际执行:
Integer i = Integer.valueOf(10);

分析Integer的valueOf源码:

public static Integer valueOf(int i) {
    if(i >= -128 && i <= IntegerCache.high)  // 没有设置的话,IngegerCache.high 默认是127
        return IntegerCache.cache[i + 128];
    else
        return new Integer(i);
}

对于–128到127(默认是127)之间的值,Integer.valueOf(int i) 返回的是缓存的Integer对象(并不是新建对象),而其他值,执行Integer.valueOf(int i) 返回的是一个新建的 Integer对象。装箱的过程会创建对应的对象,这个会消耗内存,所以装箱的过程会增加内存的消耗,影响性能。

*** 拆箱原理**

封装类–>基本数据类型

Integer i = 10; //装箱 
int t = i; //拆箱,实际上执行了 int t = i.intValue();

intValue()源码:

@Override
 public int intValue() {
    return value;
}

面试题:

int与Integer不同与比较?

  • 不同

  • 1、Integer是int的包装类,int则是java的一种基本数据类型

  • 2、Integer变量必须实例化后才能使用,而int变量不需要

  • 3、Integer实际是对象的引用,当new一个Integer时,实际上是生成一个指针指向此对象;而int则是直接存储数据值

  • 4、Integer的默认值是null,int的默认值是0

  • 比较

  • 由于Integer变量实际上是对一个Integer对象的引用,所以两个通过new生成的Integer变量永远是不相等的(因为new生成的是两个对象,其内存地址不同)。

  • 、Integer变量和int变量比较时,只要两个变量的值是相等的,则结果为true(因为包装类Integer和基本数据类型int比较时,java会自动拆包装为int,然后进行比较,实际上就变为两个int变量的比较)

  • 非new生成的Integer变量和new Integer()生成的变量比较时,结果为false。(因为非new生成的Integer变量指向的是java常量池中的对象,而new Integer()生成的变量指向堆中新建的对象,两者在内存中的地址不同)

  • 对于两个非new生成的Integer对象,进行比较时,如果两个变量的值在区间-128到127之间,则比较结果为true,如果两个变量的值不在此区间,则比较结果为false。

  • 原因:java对于-128到127之间的数,会直接从缓存中取,故相等。否则创建一个新的对象,故不等。

理解String为什么设计为不可变的?

  • 在Java程序中String类型是使用最多的,这就牵扯到大量的增删改查,每次增删改差之前其实jvm需要检查一下这个String对象的安全性,就是通过hashcode,当设计成不可变对象时候,就保证了每次增删改查的hashcode的唯一性,也就可以放心的操作
  • 字符串值是被保留在常量池中的,也就是说假若字符串对象允许改变,那么将会导致各种逻辑错误
  • 网络连接地址URL,文件路径path通常情况下都是以String类型保存, 假若String不是固定不变的,将会引起各种安全隐患。

String,StringBuffer,StringBuilder区别?

上面有图表解析

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值