泛型 的好处:
1. 把运行时出现 的问题提前至了编译时。
2. 避免了无谓的强制类型转换。
在泛型中不能使用基本数据类型,如果需要使用基本数据类型,那么就使用基本数据类型对应的包装类型。
只能是引用类型
byte----> Byte
short---> Short
int----> Integer
long----> Long
double ----> Double
float -----> Float
boolean-----Boolean
char-------》 Character
泛型在集合中的应用:
ArrayList list = new ArrayList(); true true true
ArrayListlist = new ArrayList(); true true false
ArrayList list = new ArrayList(); false true false
考虑到新老系统兼用性:
ArrayList list = new ArrayList(); false false true
ArrayList list = new ArrayList(); true false false
注意: 在泛型中没有多态的概念,两边的数据必须要一致。 或者是只写一边 的泛型类型。
推荐使用: 两边的数据类型都写上一致的。
1>函数定义泛型
泛型方法:
泛型方法的定义格式:
修饰符 <声明自定义泛型>返回值类型 函数名(形参列表..){
}
注意:
1. 在方法上的自定义泛型的具体数据类型是调用该方法的时候传入实参的时候确定的。
2. 自定义泛型使用的标识符只要符合标识符的命名规则即可。
public static void main(String[] args) {
Integer i= print(12); // Integer
String str = print("abc");
}
// 把T字母声明为自定义 的泛型、
public static abc print(abc o){
return o;
}
2>类定义函数
泛型类的定义格式:
class 类名<声明自定义的泛型>{
}
注意的事项:
1. 在类上自定义的泛型的具体数据类型是在创建对象的时候指定的。
2. 在类上自定义了泛型,如果创建该类的对象时没有指定泛型的具体类型,那么默认是Object类型。
//自定义 一个集合对象
class MyList{
Object[] arr = new Object[10];
int index = 0;
public MyList(){
}
public void add(T o){
arr[index++] = o;
}
}
public class Demo3 {
public static void main(String[] args) {
MyList list= new MyList();
list.add("123");
MyList list2 = new MyList();
new ArrayList();
}
}
3>接口定义泛型
泛型接口的定义格式:
interface 接口名<声明自定义的泛型>{
}
在接口上自定义泛型要注意的事项:
1. 在接口上自定义泛型的具体数据类型是在实现该接口的时候指定的。
2. 如果一个接口自定义了泛型,在实现该接口的时候没有指定具体的数据类型,那么默认是Object数据类型。
如果想在创建接口实现类对象的时候再指定接口自定义泛型 的具体数据类型?
interface Dao{
public void add(T t);
public void remove(T t);
}
public class Demo4 implements Dao{
public static void main(String[] args) {
new Demo4();
}
@Override
public void add(T t) {
// TODO Auto-generated method stub
}
@Override
public void remove(T t) {
// TODO Auto-generated method stub
}
}
泛型的上下限:
泛型中通配符: ?
? super Integer : 只能存储Integer或者是Integer父类元素。 泛型 的下限
? extends Number : 只能存储Number或者是Number类型的子类数据。 泛型上限