关于Java的泛型,是我们接触集合之后经常遇到和使用的一个key点,那么泛型是什么怎么用哪?
开篇例子:public class Cash<T> {
T object;
public void setValue(T t){this.object=t;}
public Object getValue(){return object;}
}
定义:泛型从字面上理解可以说是广泛的参数类型,而规范的说是:参数化类型,也就是将一个类型当做一个参数传递给类或方法。
关于泛型的特点:
1,泛型相对于使用Object的粗暴的类型来说,他可以将数据的类型像参数一样传递给类或方法。它提供了一种扩展能力。体现了一种面向抽象开发的编程宗旨。
2、当具体的类型确定后,泛型又提供了一种类型检测的机制,只有相匹配的数据才能正常的赋值,否则编译器就不通过。所以说,它是一种类型安全检测机制,一定程度上提高了软件的安全性防止出现低级的失误。
3、泛型提高了程序代码的可读性,不必要等到运行的时候才去强制转换,在定义或者实例化阶段,因为这个类型显化的效果,程序员能够一目了然猜测出代码要操作的数据类型。
泛型的分类:
1.泛型类
1)
class Test<T>{
//这里的T只是一个泛型标示符可以用任何大写的字母表示
//不过多用: T 代表一般类
//E 代表Element 或Exception
//K表示Key
//V表示Value,v和k多一起使用
//S表示SubType
T field1;
}
像上面的这样的类叫做泛型类,这里的T 也可以替换成Integer或String的引用类型,这是就表示具体类型的类
2.泛型方法
1)class Test{
public <T> T func(T t){
return null;
}
}
泛型方法与泛型类稍有不同的地方是,类型参数也就是尖括号那一部分是写在返回值前面的。
<T>
中的 T 被称为
类型参数,而方法中的 T 被称为参数化类型,它不是运行时真正的参数。【有时候类是泛型的同时,方法也是泛型的这是,类的泛
型T 不一定和方法的泛型T是一个了类型】
class Test<T>{
public <T> T func1(T t){
retturn null;
}
//这里不要上边的T和方法中的T是同一个类型,泛型方法始终以自己定义的类型参数为准
}
3.泛型接口
1)public interface interator<T>{}
关于泛型接口和泛型类十分相似,不做详解
4.泛型通配符<?>
讲到泛型还有一个这是点必须要提,那就是泛型通配符<?>
1)关于通配符,这里凡是用T的地方都可以替换为?通配符
2)通配符的分类:
a.无限通配符 <?>
b.上限通配符<? extends T>
c.下限通配符 <? super T>
3)通配符这里有一个区别点就是,当使用通配符时候,某些类会丧失其方法,变成Object,原有类型方法编译不通过。例如下面:
static void test(Collection<?> collection) {//这里的collection是无限泛型
collection.add(new Object());//编译错误,这里编译不通过
}
collection.add(new Object());//编译错误,这里编译不通过
}
解答:有人说,
<?>
提供了只读的功能,也就是它删减了增加具体类型元素的能力,只保留与具体类型无关的功能。它不管装载在这个容器内的元素是什么类型,它只关心元素的数量、容器是否为空?我想这种需求还是很常见的吧
5.类型擦除
关于泛型的类型擦除,这里我就举一个例子说吧:
List<?> list=new ArrayList<>();
List<?> list2=new ArrayList<>();
List<?> list2=new ArrayList<>();
System.out.println(sList.getClass()==iList.getClass());//这个结果是true,原因就是,list和list2是同属于一个类ArrayList的,所以二者的类类型相同,但是对象不相同