![8d2ad87ce941e7b891422f8926742ec7.png](https://img-blog.csdnimg.cn/img_convert/8d2ad87ce941e7b891422f8926742ec7.png)
作者:BossXiang
出自:五角钱的程序员
原文:mp.weixin.qq.com/s/HNGiLunl7DbVws8S6AtsAg
泛型的使用场景,可以作用在什么位置,使用泛型有什么好处,灵魂三连问???
![f15ff7162bf00150768c5e28fa9f305f.png](https://img-blog.csdnimg.cn/img_convert/f15ff7162bf00150768c5e28fa9f305f.png)
一、什么是泛型,泛型有什么用
1.泛型就是一种未知的类,将未知的类型声明在集合、对象上,泛型的默认类型为Object。
例如:ArrayList<String> str = new ArrayList<String>();
这是将String类型指定在str这个集合内,这个集合存储或者读取的类型只能为String类型。
2.使用泛型可以在传参的时候(使用占位符 ? 占位)不固定传入什么类型,即可通用类型,如果不设置泛型的上限(例如:< ? extends List>)和下限(例如:<? super List>)。
3.使用泛型后对象或者集合内只能放入指定的数据类型,可以保证对象或者集合的安全性,减少类型的转换操作。
二、java泛型三大使用场景
泛型只能定义引用数据类型,而不能使用基本数据类型 泛型类、泛型接口、泛型方法
1.泛型类
最常见的泛型类就属容器类了。实现了一个简单的Container,非常简单…非常非常…
以下是代码
public class Container1 {
private String key;
private String value;
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
@Override
public String toString() {
return "Container1{" +
"key='" + key + ''' +
", value='" + value + ''' +
'}';
}
}
所有的 key 和 value 都是字符串。类型被写死。这种集合类的可用场景就十分局限。
下面使用泛型来重新定义这个类
public class Container2<K,V> {
K key;
V value;
public K getKey() {
return key;
}
public void setKey(K key) {
this.key = key;
}
public V getValue() {
return value;
}
public void setValue(V value) {
this.value = value;
}
@Override
public String toString() {
return "Container2{" +
"key=" + key +
", value=" + value +
'}';
}
}
看上去棒极了!在编译期间是不知道 K 和 V 的具体类型的,只有在运行时才会根据类型来具体分配内存。灵活性极高!
2.泛型接口
最常看见的泛型接口是 List,它是这样定义的
public interface List<E> extends Collection<E>
我也学习它,定义一个我的泛型接口
public interface MyIter<T> {
T next();
}
接下来给接口定义实现
public class MyIterImpl implements MyIter<String>{
@Override
public String next() {
String str = String.valueOf("str:"+System.currentTimeMillis());
return str;
}
}
public class MyIterImpl2 implements MyIter<Long> {
@Override
public Long next() {
return System.currentTimeMillis();
}
}
可见,MyIterImpl生成的都是 String 类型,而MyIterImpl2 生成的都是 Long 类型,这是在定义时就定好的。
我们来使用一下!
public class test {
public static void main(String[] args) {
MyIterImpl m = new MyIterImpl();
System.out.println(m.next());
MyIterImpl2 m1 = new MyIterImpl2();
System.out.println(m1.next());
}
}
![0e7a7edb5289f3c3aea4cc3215faee10.png](https://img-blog.csdnimg.cn/img_convert/0e7a7edb5289f3c3aea4cc3215faee10.png)
3.泛型方法
定义泛型方法,有一套对应的语法
<Class> 返回值 方法名(泛型变量) // 描述的不是很清楚
我也试着定义了一个泛型方法。
public static <T> void print(T t) {
System.out.println(t);
}
可见,方法的参数彻底的泛型化了。编译器自动帮我们做了类型推导。这样在定义方法的时候不必考虑参数的类型,大大增加了灵活性。
让我们尽情使用他吧!
public class method {
public static <T> void print(T t){
System.out.println(t);
}
public static void main(String[] args) {
print("123");
print(999);
print(false);
print(11.1D);
}
}
![d036bd6692172e23ff5c99a9ced53d96.png](https://img-blog.csdnimg.cn/img_convert/d036bd6692172e23ff5c99a9ced53d96.png)
三、使用泛型的好处
1.使用泛型后对象或者集合内只能放入指定的数据类型,避免出现对象或者集合内的对象在多态使用的时候出现类型转换异常(java.lang.ClassCastException)
2.指定了类型后,对象、集合或方法内只能使用对应的类型,可以减少类型的转换操作(在没有指定类型是类型转换必须使用 instanceof 关键字来进行判定