Java字符串比较 == 和 equals 的区别 intern


一、== 和 equals 的区别?

==:如果⽐较的对象是基本数据类型,则⽐较的是数值是否相等;如果⽐较的是引⽤数据类型,则⽐较的是对象的地址值是否相等。
equals ⽅法:⽤来⽐较两个对象的内容是否相等。注意:equals ⽅法不能⽤于⽐较基本数据类型的变量。如果没有对 equals ⽅法进⾏重写,则⽐较的是引⽤类型的变量所指向的对象的地址(很多类᯿新了 equals ⽅法,⽐如String、Integer 等把它变成了值⽐较,所以⼀般情况下 equals ⽐较的是值是否相等)。

二、Java字符串比较

    public static void test1() {
        String s1 = "a" + "b" + "c";  // 得到 abc的常量池
        String s2 = "abc"; // abc存放在常量池,直接将常量池的地址返回
        /**
         * 最终java编译成.class,再执行.class
         */
        System.out.println(s1 == s2); // true,因为存放在字符串常量池
        System.out.println(s1.equals(s2)); // true
    }

	public static void test2() {
        String s1 = "javaEE";
        String s2 = "hadoop";
        String s3 = "javaEEhadoop";
        String s4 = "javaEE" + "hadoop";    
        String s5 = s1 + "hadoop";
        String s6 = "javaEE" + s2;
        String s7 = s1 + s2;
        /**
        s1 + s2的执行细节
- StringBuilder s = new StringBuilder();
- s.append(s1);
- s.append(s2);
- s.toString();  -> 类似于new String("ab");
- 也就相当于是new的对象(new的是在堆空间里面的),而不是跟s1这种字面量方式赋值一样存放在字符串产常量池中的
        */
        

        System.out.println(s3 == s4); // true s4的写法和s3的值是一样的,s4在java文件编译为.class的时候,就直接变成了javaEEhadoop
        System.out.println(s3 == s5); // false 因为s5是new的方式创建的,只要后面拼接的是变量,s5就是一个对象,实现通过StringBuilder拼接起来了
        System.out.println(s3 == s6); // false
        System.out.println(s3 == s7); // false
        System.out.println(s5 == s6); // false
        System.out.println(s5 == s7); // false
        System.out.println(s6 == s7); // false

        String s8 = s6.intern();//intern方法,则会判断字符串常量池中是否存在JavaEEhadoop值,如果存在则返回常量池中的值,否者就在常量池中创建
        System.out.println(s3 == s8); // true 
    }

/*
    1. 字符串拼接操作不一定使用的是StringBuilder!
       如果拼接符号左右两边都是字符串常量或常量引用,则仍然使用编译期优化,即非StringBuilder的方式。
    2. 针对于final修饰类、方法、基本数据类型、引用数据类型的量的结构时,能使用上final的时候建议使用上。
     */
    @Test
    public void test4(){
        final String s1 = "a";
        final String s2 = "b";
        String s3 = "ab";
        String s4 = s1 + s2;
        System.out.println(s3 == s4);//true
    }
String s11 = "a";
String s22 = "bc";

String s1 = "abc";
String s2 = "a" + "bc";
String s3 = new String("a") + "bc";
String s4 = new String("a") + new String("bc");
String s5 = new String("abc");
String s6 = s11 + s22;

System.out.println(s1 == s2);
System.out.println(s1 == s3);
System.out.println(s1 == s4);
System.out.println(s1 == s5);
System.out.println(s1 == s6);
System.out.println(s3 == s4);
System.out.println(s4 == s5);

System.out.println(s1 == s5.intern());
System.out.println(s1 == s6.intern());

System.out.println(s1.equals(s5));
System.out.println(s1.equals(s6));

输出结果:

true
false
false
false
false
false
false

true
true

true
true

解析:

“==“符号是判断地址是否相等,所以每次"new String(””)“都会有自己地址空间所以s1和s3,s4,s5为"false”。而s1和s6为什么也为"false"呢?这是因为字符串变量相加会额外创建StringBuilder调用append方法,之后会StringBuilder转换String,在此会new对象,因此也为false。

//StringBuilder的toString方法,这里会new String
@Override
public String toString() {
    // Create a copy, don't share the array
    return new String(value, 0, count);
}

“equals"只是判断值是否相等,所以s1和s5,s6为"true”。

"intern"字符串的值输出无任何变化,在调用s5.intern()方法的时候会返回”abc”,但是这个方法会首先检查字符串池中是否有”abc”这个字符串,如果存在则返回这个字符串的引用,否则就将这个字符串添加到字符串池中,然会返回这个字符串的引用。

三、在JVM中JAVA String a = “abc“ 中发生了什么

在JVM中JAVA String a = “abc“ 中发生了什么

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值