包装类
面试题
1:String为什么是不可变的
从源码可看出,String类中有一个Byte[ ]数组,这个Byte[ ]数组采用了final修饰,
因为数组一旦被创建,长度不可变。并且被final修饰的引用一旦指向某个对象之后不可以
再指向其他对象,所以String是不可变的
2:StringBuilder(线程不安全)/StringBuffer(线程安全)为什么是可变的
从源码可知,StringBuilder/StringBuffer内部实际是一个Byte[ ]数组,这个Byte[ ]数组没有被final修饰,StringBuilder/StringBuffer的初始化容量是16,当存满之后会进行扩容,底层调用了数组拷贝的方法,System.arraycopy()....是这样扩容的。所以StringBuilder/StringBuffer适合使用字符串的频繁拼接操作。
8基本数据类型的包装类
包装类 父类
Byte Number
Short Number
Integer Number
Long Number
Float Number
Double Number
Boolean Object
Character Object
学习代码
package integerTest;
public class IntegerTest {
public static void main(String[] args) {
//测试包装类型数据与未包装数据大小
test01();
//测试拆箱与装箱
test02();
//测试构造方法
test03();
}
public static void test01() {
//自动装箱
Integer age1=5555;
Integer age2=5555;
//自动拆箱
int age3=18;
int age4=18;
int age5=5556;
int age6=5556;
Integer age7=12;
Integer age8=12;
//装箱类当在常量池范围外,比较的是内存地址。比较大小时用equals方法
//源码注释:// range [-128, 127] must be interned (JLS7 5.1.7)
System.out.println(age1==age2); //false [-128, 127]常量池范围,当定义的包装类在这个范围时,不会创建一个新对象
System.out.println(age1.equals(age2)); //true
System.out.println(age3==age4); //true
System.out.println(age5==age6); //true
System.out.println(age8==age7); //true
age7+=127;
age8+=127;
//当对包装类型数据做运算超出常量池范围,则会自动创建一个新对象。应该是自动装箱了
System.out.println(age8==age7); //false
}
public static void test02() {
//基本数据类型装换为--->引用数据类型(装箱)
Integer i=new Integer(555);
//引用数据类型--->基本数据类型(拆箱)
float f=i.floatValue();
System.out.println(f);//555.0
//引用数据类型--->基本数据类型(拆箱)
int retValue=i.intValue();
System.out.println(retValue);//555
}
public static void test03() {
//Java9之后是过时方法
//将数字100转换为Integer包装类型
Integer x = new Integer(100);
System.out.println(x);
//将字符100转换为Integer包装类型
Integer m = new Integer("100");
System.out.println(m);
}
}