测试代码
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
s5s2false
s1,s3都是常量池里面的*true
s3是常量池里面的*s2是堆里面的false
s8s9***true
s11s9***false
s12s9***false
s13s9***false
s14s9***true
-128到127从常量池拿 a1a2***true
大于127从堆里拿 a3a4***false
a5a6***false
a5==a9***true
Process finished with exit code 0