Object类可以接受所有引用数据类型。然而在Java中,数据类型分为基本数据类型和引用数据类型那么基本数据类型如何处理呢?所以在Java中我们为了处理基本数据类型,就出现了包装类。
包装类的基本原理
包装类就是将基本数据类型封装到类中。
范例:自己定义一个包装类
class IntDemo{
private int val;
public IntDemo(int val){
this.val=val;
}
public int intValue(){
return this.val;
}
}
public class Test {
public static void main(String[] args) {
IntDemo intDemo=new IntDemo(10);
System.out.println(intDemo.intValue()+20);
}
}
这个时候的IntDemo实际上就是int数据类型的包装类,利用IntValue就可以实现基本数据类型变为对象的需求。
范例:IntDemo的使用
public class Test {
public static void main(String[] args) {
IntDemo intDemo=new IntDemo(20);
Object obj=new Object();
//向下转型,需要强转
obj=new IntDemo(10);
intDemo=(IntDemo)obj;
System.out.println(intDemo.intValue()+20);//取出里面的基本数据类型进行操作
}
}
结论:将基本类型包装为一个类对象的本质就是使用Object进行接收处理,这样Object类就可以接收Java中所有的数据类型。
包装类的分类
Java中有8种数据类型,如果每种数据类型都按照以上方式编写,就会存在一下问题:
1.开发中代码重复
2.在进行数学计算的时候,必须利用明确的方法将包装的数据取出来后才可以进行运算。所以Java为了方便开发,专门提供了包装类的使用,而对于包装类的使用,提供了两种类型。
对象型包装类
对象型包装类(Object的直接子类),有两种:Boolean(boolean)和Character(char)
数值型包装类
数值型包装类(Number的直接子类),有六种:Byte(byte)、Double(double)、Short(short)
、Long(long)、Integer(int)、Float(float)
装箱与拆箱
在包装类与基本数据类型处理中存在两个概念:
装箱:将基本数据类型变为包装类对象,利用每一个包装类提供的构造方法实现装箱处理。
拆箱:将包装类中包装的基本数据类型取出。利用Number类中提供的XXValue()实现拆箱处理。
范例:以int和Integer举例
public class Test {
public static void main(String[] args) {
//装箱
Integer i=new Integer(10);
//拆箱
int ret=i.intValue();
System.out.println(ret+20);//取出里面的基本数据类型进行操作
}
}
以上的操作采用的是手工的装箱和拆箱。在JDK1.5之后,提供了自动拆箱装箱的机制,最为重要的是,由于此类机制的存在,可以直接利用包装类的对象进行各种数学计算。
范例:自动装箱与拆箱处理
public class Test {
public static void main(String[] args) {
//自动装箱
Integer i=10;
//自动拆箱
int ret=i+20;
System.out.println(ret);
}
}
这个时候依然存在有“==”和“equals”问题
阿里编码规范:所有相同类型的包装类对象之间值的比较,全部使用equals方法比较。
范例:
public class Test {
public static void main(String[] args) {
Integer num1=new Integer(10);
Integer num2=10;
Integer num3=10;
Integer num4=200;
Integer num5=200;
System.out.println(num1==num2);//false
System.out.println(num2==num3);//true
System.out.println(num4==num5);//false
}
}
我们来观察上面代码的执行结果,“= =”比较的是堆上的内存地址,num1和num2所指向的内存地址不一样,所以输出false;当没有重新开辟空间的时候,num2和num3会有一个入池操作,两个对象指向同一个堆内存,所以输出true;那么问题来了,按理来说num4和num5也应该入池两个对象指向同一个堆内存,输出true,但是最后结果输出false呢?
说明:对于Integer var=?在-128值127范围内的赋值,Integer对象是在对象池中产生,会复用已有的对象,这个区间内的Integer值可以直接使用“= =”进行判断,但是这个区间之外的所有数据,都会在堆上产生,并不会复用已有对象,这是一个大坑,推荐使用equals方法进行值判断。
阿里编码规范:使用int还是Integer?
- 【强制】所有的POJO(简单Java类,Bean(只有基本属性、构造方法和getter、setter))类属性必须使用包装数据类型。
- 【强制】RPC(远程方法调用)方法的返回值和参数必须使用包装数据类型。
- 【推荐】所有的局部变量使用基本数据类型。
字符串与基本类型转换
以后进行各种数据的输入,一定都是字符串类型的接收。所以在开发之中,如何将字符串变为各个数据类型,这个时候就需要包装类支持。
1.String变为int类型(Integer类):
public static int parseInt(String s)
2.String变为double类型(Double类):
public static double parseDouble(String s)
3.String变为Boolean类型(Boolean类):
public static boolean parseBoolean(String s)
范例:将字符串变为int型
public class Test {
public static void main(String[] args) {
String str1="123";
int num1=Integer.parseInt(str1);
System.out.println(num1);
}
}
范例:将字符串变为double型
public class Test {
public static void main(String[] args) {
String str2="123.123";
double num2=Double.parseDouble(str2);
System.out.println(num2);
}
}
需要注意的是,将字符串转为数字的时候,字符串的组成有非数字,那么转换就会出现错误(NumberFormatException)。但是字符串与boolean转换就不受此影响。
范例:
public class Test {
public static void main(String[] args) {
String str1="hello HL";
boolean bol=Boolean.parseBoolean(str1);
System.out.println(bol);//false
}
}
那么如果现在要将基本数据类型变为字符串:
1.任何数据类型使用了“+”链接空白字符串就变为了字符串类型。
2.使用String类中提供的valueOf()方法,此方法不产生垃圾。
范例:
public class Test {
public static void main(String[] args) {
int num=12345;
String str1=num+"HL";
System.out.println(String.valueOf(num));
System.out.println(str1);
}
}