1.什么是泛型
我们经常使用的ArrayList类后面常常有一个< >符号,如下
public class Test{
public static void main(String[] args){
ArrayList list = new ArrayList ();
list.add ("hello");
list.add (10);
list.add (new User());
// 存储
ArrayList<String> list1 = new ArrayList ();
list1.add(" ");
list1.add(100);
}
}
这里面的<String>就是我们所说的泛型的应用,这里面使用<String>表示这个ArrayList里面存储的对象只能是字符串。
2.使用泛型的好处
首先我们写在<>中的类型不能是基本数据类型(如int),只能用封装数据类型替代(如int就可以用它对应的封装类型Integer,char就可以用String替代,我们可以在java.lang中查看封装数据类型有哪些)。
我们使用了封装类以后就需要用封装类型去定义变量、赋值,封装类它可以自动装箱和自动拆箱。自动装箱和自动拆箱就让我们在使用封装类的时候也可以像使用基本数据类型一样方便(效果如下)。
package com.shapepro.zyf1016;
import com.oop.zyf1006.User;
import java.util.ArrayList;
public class Test{
public static void main(String[] args){
// 存储结构 一定要限制存储的类型 ,不然结构中什么类型的数据都可以存入,不方便管理
// 不带类型限制的 什么数据都可以存储
ArrayList list = new ArrayList ();
list.add ("hello");
list.add (10);
list.add (new User ());
// Object obj = list.get (?);
// 存储 带<类型> 就会限制存储的对象类型
// String 只能存储 字符串
ArrayList<String> list1 = new ArrayList ();
list1.add(" ");
// list1.add(100);
// <> 中不能写 基本数据类型 八个 使用封装类型替代
// ArrayList<int> list2 = new ArrayList ();
ArrayList<Integer> list3 = new ArrayList ();
list3.add (100);
// 装箱 将基本数据类型的变量赋值给 封装类型 变量
int i =128;
Integer i2 = i;
Integer i3 = 128;// 与使用基本数据类型赋值是一样的
System.out.println (i2==i3);// 比较的是地址
System.out.println (i2.equals (i3));
// 拆箱 将封装数据类型变量 转为 基本数据类型变量
Integer i4 = new Integer (300);
int i5 = i4;
}
}
可以看到装箱后将基本数据类型的变量赋值给封装类型变量是可以的,封装类型变量的赋值也和基本数据类型一致。
3.泛型使用的用法
- 声明泛型:
- 类名的右边加上 <>
- <> 中 写一个通配符 任何单词 字母都可以 E 表示元素
- 通配符:
- 可以用来声明参数类型
- 可以用来声明返回值类型
示例(List):
package com.shapepro.zyf1016;
/**
* 自定义实现的List
*/
public class MyList<E>{
// 存储结构 : Object[]
// 所有数据类型的父类
Object[] values = {};
int index;
int size;
int length;
// 初始化的构造方法 创建对象时传入一个初始容量
public MyList(int initialCapacity){
// 初始化属性
if(initialCapacity < 0){
throw new IllegalArgumentException ("initialCapacity can not < 0");
}
length = initialCapacity;
values = new Object[length];
index = 0;
size = 0;
}
public void add(E e){
// 每次存储前 先检查存储结构 数组的容量是否足够
if(index == length){
// 扩容
// 先计算扩容大小
int oldLength = length;
int newLength = oldLength + (oldLength >> 1);
length = newLength;
// 初始一个空的 新的 大的数组
Object[] newarr = new Object[length];
// 将原数组中的元素全部移动到 新数组中
for(int i = 0; i < oldLength; i++){
newarr[i] = values[i];
}
// 用原本数组对象变量名 存储 新数组对象变量名中的引用地址
values = newarr;
// 新数组变量名 就没用了,设置为null
newarr = null;
}
// 将对象存入数组中
values[index] = e;
index++;
size++;
}
public E get(int index){
if(index>=0&&index < length){
Object obj = values[index];
// 将取出的Object 类型的对象 强制转换为 E 类型
return (E)obj;
}
throw new ArrayIndexOutOfBoundsException ("inde:"+index+" length:"+length);
}
public static void main(String[] args){
MyList list = new MyList (10);
for(int i = 0; i < 30; i++){
list.add ("hello");
list.add (10);
}
Object obj = list.values[25];
// String str = (String)obj;
// System.out.println (str);
MyList<String> list1 = new MyList (10);
for(int i = 0; i < 30; i++){
list1.add ("hello");
// list1.add (10);// 此处受到了泛型的限制
}
System.out.println (list1.get (15));
}
}