包装类
Java是一个面向对象的编程语言,而Java中的八种基本数据类型不是面向对象的,所以它不能直接参与面向对象编程的,为了解决这个问题,Java为每种基本数据类型都提供了一个对应的包装类,这些包装类属于java.lang包,所以它不需要额外导入。
1.1 基本数据类型和对应的包装类
除了 Integer 和 Character, 其余基本类型的包装类都是首字母大写。
装箱和拆箱
1.装箱
public class Test {
public static void main(String[] args) {
Integer a=10;//装包(也是隐式装箱或自动装箱)
int i=99;
Integer b=i;//也是装包,这个意思是把一个基本数据类型给到了引用数据类型
//上面这两个可以正常输出a,b
System.out.println(a);
System.out.println(b);
Integer aa=Integer.valueOf(10);//显示装箱
}
}
这里我们比较关心字节码文件是怎么做的,来看一下:
如上图我们可以发现,在赋值的过程中,都调用了Interger.valueOf()方法,如上下面图代码是他的源码。(所以在把基本数据类型给到包装类型的过程中调用了一个方法叫valueOf()方法)
2.拆箱
public class Test1 {
public static void main(String[] args) {
Integer a=10;//自动拆箱
int i=a;
System.out.println(a);//10
int aa=a.intValue();//显示拆箱
double d=a.doubleValue();//显示拆箱
System.out.println(d);//10.0
}
}
如上图右边我们可以发现,先调用valueOf进行拆箱,再调用valueOf进行装箱。
这就是包装类,它提供了很多现成的方法直接可以用,不要我们自己写,很方便。
接下来看一个题:
public class Test1 {
public static void main(String[] args) {
Integer a=100;
Integer b=100;
System.out.println(a==b);
Integer a1=200;
Integer b1=200;
System.out.println(a1==b1);
}
如上图我们可以看见有两个比较相等的地方,判断他们是否相等?
结果如下:
为什么是这样的结果呢?如果让我们排查,我们要从哪里开始排查呢?
因为在赋值的时候相当于在装包,装包会调用valueOf()方法,所以我们因该看下valueOf()做了什么,为什么经过装包就不对了了。如下图:
low=-128
high=127
i的范围是[-128,127]
就是说如果i在[-128,127]这个范围里面,可直接去某个下标拿(如上图红色框里面的值),因为都在这个数组中,所以相等,如果不在这个数组范围中,就去new,而每次new就会产生新的对象,新的对象会产生新的地址,所以a1和b1的地址不一样,他们就不想等。
上面讲的不是很好,这里推荐https://blog.youkuaiyun.com/qq_29119581/article/details/78327759
泛型
1.什么是泛型(也是一种语法)
(通俗来讲,就是泛型可以存放自己指定的类型,在类型的后面,使用<>来指定的,而这个类型作用就是在编译的时候,帮我们进行类型检查,比如<Integer>,后面检查的时候都是以Integer进行检查的)
一般的类和方法,只能使用具体的类型: 要么是基本类型,要么是自定义的类。如果要编写可以应用于多种类型的代码,这种刻板的限制对代码的束缚就会很大。
泛型是在JDK1.5引入的新的语法,通俗讲,泛型:就是适用于许多许多类型。从代码上讲,就是对类型实现了参数化。
2.语法:
引出泛型
首先,在引出泛型之前,我们来实现一个类,类中包含一个数组成员,是的数组中可以存放任何类型的数据,也可以根据成员方法返回数组中某个下标的值?
如上图这处错误,这个数组什么都能放,明显1下表是字符串,为什么拿字符串还会报错呢?
原因很简单,因为getValue返回值Object在这个过程中向下转型是需要强转的。
所以,我们当前这样写有一个不好的地方,虽然它什么类型都可以放,但是他放的太乱了,而且每次取的时候都要强转。能不能指定什么放什么,不需要强转,比如指定int放int,指定String放String,为了解决这个问题,因此我们引入了泛型,那接着往下看:
如上图,当在MyArray<Integer> myArray=new MyArray<Integer>();写了<Integer>之后,myArray.setValue(1,"hello");立马报错,为什么报错呢?原因是制定了当前的 MyArray是Integer,所以在编译的时候发现myArray.setValue(1,"hello");中"hello"不是Integer,把他改成Integer即可。所以在这个过程当中String str= (String) myArray.getValue(1);就不能这样写了,也不需要强转了,因为MyArray指定的是Integer,他就是Integer。修改如下:
那如果放String,会不会不通用呢?答案是不会,如下:
代码结果如下:
为什么学包装类,是因为如上代码过程中不能放基本类型,不然会报错,所以这个过程中只能放包装类或引用类型,这就叫泛型,所以什么是泛型呢?他就是将类型进行了传递。
注意:
好了,泛型就了解到此处吧,大家也可以看看其他博客,以了解的更深。