网站首页 > 精选教程 正文
临近年关各种忙,
检查代码想撞墙,
年会聚餐怎么样,
我只关心年终奖。
------------------------------打油诗分割线---------------------------
泛型,java中的语法糖,为了代码优化,增强可读性及类型转换的方式。
泛型的主要使用:泛型类,接口,泛型方法。
想了解泛型,得先知道一个概念:
类型擦除:
Java中的泛型基本上都是在编译器这个层次来实现的。在生成的Java字节码中是不包含泛型中的类型信息的。使用泛型的时候加上的类型参数,会被编译器在编译的时候去掉。这个去掉的过程就是类型擦除。
下面可以看一段代码:
public static void main(String[] args) {
ArrayList c1 = new ArrayList<String>();
ArrayList c2 = new ArrayList<Integer>();
}
在编译之后,得到的结果如下:
可以看出,编译器并没有记录具体类型,因为泛型在编译过程中,已经被编译器替换掉了。
这就带来了一些问题,如下代码所示:
public class Erased<T> {
private static final int SIZE = 100;
public void f(Object arg) {
if(arg instanceof T) {} // Cannot perform instanceof check against type parameter T
T var = new T(); // Cannot create a generic array of T
T[] array = new T[SIZE]; //Cannot create a generic array of T
T[] array1 = (T[])new Object[SIZE]; //Type safety: Unchecked cast from Object[] to T[]
}
}
许多运行期才能知道确切类型的代码,都会编译不通过。
泛型修饰类:
如代码所示,定义一个泛型类,在创建实例时,会根据传入的具体类型创建对应的实例。
public class Generics<T> {
private T arg;
public String f(T arg) {
return arg.toString();
}
public static void main(String[] args) {
Generics<String> generics = new Generics<String>();
String s = generics.f("111");
System.out.println(s);
}
}
泛型修饰方法:
如代码所示,返回值前的<K> 不能省略,否则就编程了泛型类中的普通方法,而不省略,则是泛型方法。
泛型方法在方法调用时根据传入的参数类型确定类型。
//泛型类
public class Generics<T> {
private T arg;
//泛型类的普通方法
public String f(T arg) {
return arg.toString();
}
//泛型方法
private static <K> K genericsType(K t)
{
return t;
}
public static void main(String[] args) {
Generics<String> generics = new Generics<String>();
String s = generics.f("111");
System.out.println(s);
Generics.genericsType(new Integer(1));
}
}
通配符:
那么,还有剩下的问题,我想更方便的使用这个类,既要传入Integer,也要传入String,如何处理呢。
如下这样会报错:
public class Generics<T> {
private T arg;
private ArrayList<T> arraylist;
public String f(T arg) {
return arg.toString();
}
private static <K> K genericsType(K t)
{
return t;
}
public static void main(String[] args) {
Generics<String> generics = new Generics<String>();
String s = generics.f("111");
System.out.println(s);
Generics.genericsType(new Integer(1));
generics.arraylist=new ArrayList<String>();
//报错,因为已经匹配了String
generics.arraylist=new ArrayList<Integer>();//Type mismatch: cannot convert from ArrayList<Integer> to ArrayList<String>
}
}
而使用通配符?后,就可以做到:
public class Generics<T> {
private T arg;
//使用通配符?
private ArrayList<?> arraylist;
public String f(T arg) {
return arg.toString();
}
private static <K> K genericsType(K t)
{
return t;
}
public static void main(String[] args) {
Generics<String> generics = new Generics<String>();
String s = generics.f("111");
System.out.println(s);
Generics.genericsType(new Integer(1));
generics.arraylist=new ArrayList<String>();
generics.arraylist=new ArrayList<Integer>();
}
}
通配符的上下界:
这个概念也很好理解,当使用通配符时,<? extends Generics> 表示某种特定类型 ( Generics或者其子类 ) 的泛型,<? super Generics>示某种特定类型 ( Generics或者其超类 ) 的泛型。因为泛型的擦除是有上界的,如果直接使用?,那么有些不关联的类,只能使用到Object的方法,因为编译器只能确定该类是Object的子类。
而使用了<? extends Generics>之后,所有的Generics类的方法,这个泛型均能使用。<? extends Generics>这种形式在很多场景中被广泛使用。
- 上一篇: 什么是语法糖?如何解糖
- 下一篇: java基础语法糖之增强for循环
猜你喜欢
- 2024-12-11 不同语言实现质因数分解算法的差异
- 2024-12-11 嫌 Java 太繁琐、表现力太差?这些 JVM 语言给你不一样的体验
- 2024-12-11 盘点C#最有价值的10个语法糖
- 2024-12-11 干货丨对Java很熟悉 但这四件事你未必知道
- 2024-12-11 promise 语法糖基本用法
- 2024-12-11 python 17个常用语法糖,学完你就是高手
- 2024-12-11 java基础语法糖之拆箱装箱
- 2024-12-11 Python中有哪些很香的语法糖?
- 2024-12-11 【python】(10)语法糖
- 2024-12-11 JS中的类?class语法糖??? 两分钟秒了
本文暂时没有评论,来添加一个吧(●'◡'●)