Java 常量池 String s4 = new String("abcd"); 创建两个对象

测试代码

package com.javabase;

/**
 * @Description: java类作用描述
 * @Author: Bsea
 * @CreateDate: 2019/6/3$ 20:57$
 */
public class StringTest2 {
    public static void main(String[] args) {
        String s1="abc";
        String s2=new String("abc");
        //每次new都会在堆里开一个新的内存空间
        String s5=new String("abc");
        //false: s1是从常量池拿数据, s2是在堆里(只要是new就是堆)
        //1.7之前,常量池在方法区,之后在堆里,独立开了一块内存放常量池
        System.out.println("s1==s2**"+(s1==s2));
        //true: String类的equals方法被重写了,比较的是里面的值
        System.out.println(s1.equals(s2));

        System.out.println("s5==s2**"+(s5==s2));
        /**
         * intern方法的作用:
         * 它的作用是:如果运行时常量池中已经包含一个
         * 等于此String对象内容的字符串,
         * 则返回常量池中该字符串的引用;如果没有,
         * 则在常量池中创建与此 String
         * 内容相同的字符串,并返回常量池中创建的字符串的引用。
         */
        String s3=s2.intern();
        System.out.println("s1,s3都是常量池里面的***"+(s1==s3));
        System.out.println("s3是常量池里面的***s2是堆里面的**"+(s2==s3));
        //这句话创建了几个对象?
        //答案:2个
        /**
         *
         * 解释:
         *
         * 先有字符串"abcd"放入常量池,
         * 然后 new 了一份字符串"abcd"放入Java堆
         * (字符串常量"abcd"在编译期就已经确定放入常量池,
         * 而 Java 堆上的"abcd"是在运行期初始化阶段才确定),
         * 然后 Java 栈的 str1 指向Java堆上的"abcd"。
         */
        String s4 = new String("abcd");

        String s6="a";
        String s7="b";
        //使用+拼接的,只有这个情况,jvm会把拼接的结果从常量池给
        //其他的所有情况,都是从堆里给
        String s8="a"+"b";
        String s9="ab";
        System.out.println("s8==s9***"+(s8==s9));
        String s10=new String("b");
        String s11="a"+s10;
        System.out.println("s11==s9***"+(s11==s9));
        String s12=s6+s7;
        System.out.println("s12==s9***"+(s12==s9));
        String s13="a"+s7;
        System.out.println("s13==s9***"+(s13==s9));
        String s14="ab"+"";
        System.out.println("s14==s9***"+(s14==s9));


        /**
         * 8种基本类型的包装类和常量池
         * Java 基本类型的包装类的大部分都实现了常量池技术,即Byte,Short,Integer,Long,Character,Boolean;这5种包装类默认创建了数值[-128,127]的相应类型的缓存数据,但是超出此范围仍然会去创建新的对象。
         *
         * 两种浮点数类型的包装类 Float,Double 并没有实现常量池技术
         */
        Integer a1=127;
        Integer a2=127;
        System.out.println("-128到127从常量池拿 a1==a2***"+(a1==a2));
        Integer a3=128;
        Integer a4=128;
        System.out.println("大于127从堆里拿  a3==a4***"+(a3==a4));

        Integer a5=10;
        Integer a6=new Integer(10);
        System.out.println("a5==a6***"+(a5==a6));
        Integer a7=5;
        Integer a8=new Integer(5);
        Integer a9=a7+a8;
        //包装类,计数过程中会自动拆箱成基本类型
        /*
        解释:

语句i4 == i5 + i6,因为+这个操作符不适用于Integer对象,
首先i5和i6进行自动拆箱操作,进行数值相加,即i4 == 40。
然后Integer对象无法与数值进行直接比较,所以i4自动拆箱转为int值40,
最终这条语句转为40 == 40进行数值比较
         */
        System.out.println("a5==a9***"+(a5==a9));







    }
}

运行结果:

s1s2**false
true
s5
s2false
s1,s3都是常量池里面的
*true
s3是常量池里面的*s2是堆里面的false
s8s9***true
s11
s9***false
s12s9***false
s13
s9***false
s14s9***true
-128到127从常量池拿 a1
a2***true
大于127从堆里拿 a3a4***false
a5
a6***false
a5==a9***true

Process finished with exit code 0

猜你喜欢

转载自blog.csdn.net/h356363/article/details/90759896