Java地基(八)补------包装类、equals与==、字符串常量池

1 包装类:将基本类型和对象类型转换

//创建对象开辟堆空间
Integer o = new Integer(1);
//自动装箱
Integer o = 1;
int i = 1;
Integer i = Integer.valueOf(20);自动装箱过程中会判断放入缓冲区还是堆区开辟空间。

integer的valueOf()源码:

        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
    }

判断拆装箱是否相等,Integer o 非创建对象当在127到-128范围内或者基本类型比较才会拆箱

jdk 1.5之前:人工操作

jdk 1.5之后:自动拆装箱

//JKD1.5 之前
Integer o = new Integer(1);
Integer o = Integer.valueOf(1);

//JDK1.5 之后
//自动装箱,这里会自动把数字1包装成Integer类型的对象
Integer o = 1;

//JKD1.5 之前
Integer o = new Integer(1);
int i = o.intValue();

//JDK1.5 之后
Integer o = new Integer(1);
//自动拆箱,这里会自动把对象o拆箱为一个int类型的数字,并把数字赋值给int类型的变量i
int i = o;

注意事项:

public class Test{
public void test1(int i){}
public void test2(Integer i){}
public void test3(long i){}
public void test4(Long i){}
	public static void main(String[] args){
		t.test1(1);//编译通过 int i = 1; 正常赋值
		t.test2(1);//编译通过 Integer i = 1; 自动装箱
		t.test3(1);//编译通过 long i = 1; 隐式类型转换
		//编译报错
		//错误的代码:Long i = 1;
		//int和Long 之间没有任何关系
		t.test4(1);
		t.test4(1L);//编译通过 Long i = 1L; 自动装箱
	}
}

2.Object中常用方法:equals

1.toString方法

可重写

默认返回:哈希值

getClass().getName()+"@"+Integer.toHexString(hashCode());

调用:

public static void main(String[] args){
	Student stu = new Student();
	//这个俩个输出语句的效果是一样的
	System.out.println(stu);
	System.out.println(stu.toString());
}

注意,默认情况下,println方法会调用这个对象的toString方法
注意,推荐使用第一种,因为当stu的值为null时,第二种输出方式会报错,空指针异常

2.getClass方法

作用:返回一个引用在运行时所指向的对象,具体类型是什么

public final native Class<?> getClass();

该方法是native修饰的本地方法,不是java语言实现的 ,无法查看源码

3. equals方法

看源码的时候我们知道他是比较地址是否相等 不是哈希值相等,但是我们一致认为他是比较值是否相等,这是因为String重写了equals方法

Object中的源码

public class Object{
	public boolean equals(Object obj) {
		return (this == obj);
	}
}

重写equals时注意:

  1. 自反性:对任意引用obj,obj.equals(obj)的返回值一定为true.
  2. 对称性:对于任何引用o1、o2,当且仅当o1.equals(o2)返回值为true时,o2.equals(o1)的返回值一定为true;
  3. 传递性:如果o1.equals(o2)为true, o2.equals(o3)为true,o1.equals(o3)也一定为true
  4. 一致性:如果参与比较的对象没任何改变,则对象比较的结果也不应该有任何改变
  5. 非空性:任何非空的引用obj,obj.equals(null)的返回值一定为false

equals与==的区别

//== 操作符
//基本类型 :值 引用类型:地址值
//equals 方法
//引用类型:没有重写方法--地址值  重写根据你重写的规则
4.hashCode方法
  • 该方法返回一个int值,该int值是JVM根据对象在内存的中的特征(地址值),通过hash算法计算出的一个结果。
  • 一个任意长度的输入转为一个固定长度的输出,是一种压缩映射,也就是说,散列值的空间通常远小于输入的空间,不同的输入可能会散列成相同的输出,所以不可能从散列值来确定唯一的输入值。
  • Object中的hashCode方法默认返回的是对象的内存地址,但是实际上可能并不是。

对于俩个对象的hashCode值:

  • 相等的俩个对象,hashCode值一定相等
  • hashCode值相同,俩个对象有可能相等,也可能不同等
  • hashCode值不同,俩个对象一定不同

3. 关于String对象:字符串常量池

字符串String,是程序中使用最多的一种数据,JVM在内存中专门设置了一块区域(字符串常量池),来提高字字符串对象的使用效率。

  • 为字符串开辟一个字符串常量池,类似于缓存区
  • 创建字符串常量时,首先会检查字符串常量池中是否存在该字符串,如果存在该字符串,则返回该实例的引用,如果不存在,则实例化创建该字符串,并放入池中 。
//只有用双引号,里面加入文字的方式,才会利用到内存中的字符串常量池。
String str1 = "hello";
String str2 = new String("hello");
//String中对equals进行了重写,比较的是字符串中每一个字符是否相等
System.out.println(str1.equals(str2));//true
//str1指向的是常量池中的hello对象
//str2指向的是堆区中新创建的hello对象
System.out.println(str1 == str2);//false

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-R2afrGyT-1622635763378)(C:\Users\86132\AppData\Roaming\Typora\typora-user-images\image-20210602141120856.png)]

经典案例:

有变量参与拼接字符串,那么就不会使用常量池了

有变量参与,就会创建堆区对象,可以使用final关键字使其变为常量

String s1 = "a";
String s2 = "b";
//使用+拼接的字符串也会利用字符串常量池
//但是有要求:参与+号拼接的必须是双引号的形式才可以。
String s3 = "a"+"b";
String s4 = s1+s2;
System.out.println(s3.equals(s4));//true
//s3指向的是常量池中的"ab"对象
//s4指向的堆区中新建的"ab"对象
//因为s4是由s1和s2使用+号连接得到的,而s1和s2都是变量
//有变量参与拼接字符串,那么就不会使用常量池了
System.out.println(s3 == s4);//false

当调用 intern() 方法时,JVM会将字符串添加到常量池中,并返回指向该常量的引用,即强制使用常量池。

String s4 = (s1+s2).intern();

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值