搜索
写经验 领红包
 > 旅游

java泛型t(java泛型方法的定义和使用)

导语:java语法糖之泛型临近年关各种忙,检查代码想撞墙,年会聚餐怎么样,我只关心年终奖。------------------------------打油诗分割线---------------------------泛型,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(); 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(); 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(); 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(); 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>这种形式在很多场景中被广泛使用。

免责声明:本站部份内容由优秀作者和原创用户编辑投稿,本站仅提供存储服务,不拥有所有权,不承担法律责任。若涉嫌侵权/违法的,请反馈,一经查实立刻删除内容。本文内容由快快网络小涵创作整理编辑!