补充面试题题: final, finally, finalize 三者的区别
- final 用来修饰变量,方法,类. 修饰类不能被继承,修饰的方法不能被重写,修饰的变量是常量(不可变).
- finally作为异常处理的一部分,配合try或者try...catch使用,他包含的代码块经常用来释放资源
- finalize()是一个方法,这个方法用来调用垃圾回收,这个地方调用该方法,不代表该对象一定会被垃圾回收,该方法只会调用一次,所以不推荐使用.
1.概念
我们之前学过数据类型,其中有以一种叫做基本数据类型(原始数据类型),里面的类型关键字都不是类名,所以没有对应的对象可以使用,为了符合面向对象的思想,方便操作,Java出现了包装类,这样,这些基本类型的数据就可以像对象一样,拥有属性和方法了.
原始数据类型 | 对应的包装类 |
btye | Byte |
short | Short |
int | Integer |
long | Long |
float | Float |
double | Double |
char | Character |
boolean | Boolean |
除了int 对应的包装类为Integer. char 对应的包装类为 Character以外
其他的基本类型的包装都是本身首字母大写的类
Java中的包装类都是final修饰,不能被继承
把八个包装类还可以分类
1.前面6个数值类型都继承了java.lang.Number这个抽象类
2.Character 和Boolean 的父类就是Object.
2. 装箱/拆箱
装箱就是指将基本数据类型转换成包装类的对象
1.手动装箱: 实际上就是通过new关键字声明空间,调用Integer的有参构造器,将int类型的变量作为参数传给Integer.
2.自动装箱: 自动装箱实际上就是调用了Integer中重写的valueOf()方法
public static Integer valueOf(int i) {
* if (i >= IntegerCache.low && i <= IntegerCache.high)
* return IntegerCache.cache[i + (-IntegerCache.low)];
* return new Integer(i); *
}
public static void main(String[] args) {
//1.手动装箱(不推荐使用)
int num1 = 300;
Integer num2 = new Integer(num1);
System.out.println("num1="+num1);
System.out.println("num2="+num2);
//2.自动装箱
Integer num3 = 300;
System.out.println("num3="+num3);
Integer num4 = Integer.valueOf(300);
System.out.println("num4="+num4);
System.out.println("==========================");
int num5 = 5;
int num6 = 6;
// System.out.println("num5==num6:"+(num5==num6));
/*包装类用==比较地址*/
System.out.println("num2==num3:"+(num2==num3));
System.out.println("num3==num4:"+(num3==num4));
}
- 直接new包装类的对象,在新版本JDK中(1.8以上)已经标记过时,不推荐使用
- JDK在自动装箱的时候,实际上是调用包装类的valueOf()方法,对于整数类型来说,该方法默认情况会对[-128,127]范围内的数据进行缓存,结果就是如果自动装箱的数据值在该范围内,不会创建新的对象,而是从缓存中拿
- 包装类之间比较建议不使用'=='因为'=='比较的是地址,而且包装类中已经重写了equals方法用来比较内容是否相等.
拆箱就是将包装类的对象转换成基本数据类型
1.手动拆箱:实际上就是返回包装类中final修饰的对应的基本类型的值
2.自动拆箱
public static void main(String[] args) {
Integer num1 = new Integer(11);
//1.手动拆箱 实际上就是返回包装类中final修饰的对应的基本类型的值
int num2 = num1.intValue();
System.out.println("num2="+num2);
//2.自动拆箱
int num3 = num1;
System.out.println("num3="+num3);
}
手动拆箱实际上调用了xxxValue()方法,需要注意的是,写xxxValue()方式实际上是重写的
java.lang.number这个抽象类中定义的抽象方法,所以Boolean 和Character 是没有这个方法的
xxxValue()方法实际上也有类型转换的功能
//其实内部的实现就是将持有的value强转成对应的基本类型
double d1 = num1.doubleValue();
System.out.println("d1="+d1);
包装类与字符串
Integer num1 = new Integer(123);
/*包装类转String*/
//1.调用重写Object的toString(),实际上是调用重载的带参数的toString(i)
String s1 = num1.toString();
System.out.println("s1="+s1);
//2.直接调用包装类的静态方法toString(i),这里传的是包装类对象,所以先自动拆箱再转换
String s2 = Integer.toString(num1);
System.out.println("s2="+s2);
String s1 = "123";
/*String转包装类对象*/
//1.直接通过包装类的构造方法,传String进去,需要注意String能否转换
//底层实际上就是将字符串转换成字符数组,然后单个字符通过ascii转换成对应数字
Double d1 = new Double(s1);
System.out.println("d1="+d1);
Integer num1 = new Integer(s1);
System.out.println("num1="+num1);
System.out.println("=============");
//2. 通过valueOf()方法,实际上就是先将字符串通过parseXXX转换后再传给valueOf方法
System.out.println(Integer.parseInt(s1));
Integer num2 = Integer.valueOf(s1);
System.out.println("num2="+num2);
Double d2 = Double.valueOf(s1);
System.out.println("d2="+d2);