java传入泛型参数_java语法糖之泛型

临近年关各种忙,

检查代码想撞墙,

年会聚餐怎么样,

我只关心年终奖。

------------------------------打油诗分割线---------------------------

泛型,java中的语法糖,为了代码优化,增强可读性及类型转换的方式。

泛型的主要使用:泛型类,接口,泛型方法。

想了解泛型,得先知道一个概念:

类型擦除:

Java中的泛型基本上都是在编译器这个层次来实现的。在生成的Java字节码中是不包含泛型中的类型信息的。使用泛型的时候加上的类型参数,会被编译器在编译的时候去掉。这个去掉的过程就是类型擦除。

下面可以看一段代码:

public static void main(String[] args) {

ArrayList c1 = new ArrayList();

ArrayList c2 = new ArrayList();

}

在编译之后,得到的结果如下:

016bafa072aa569096061cbfda8c1378.png

可以看出,编译器并没有记录具体类型,因为泛型在编译过程中,已经被编译器替换掉了。

这就带来了一些问题,如下代码所示:

public class Erased {

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 {

private T arg;

public String f(T arg) {

return arg.toString();

}

public static void main(String[] args) {

Generics generics = new Generics();

String s = generics.f("111");

System.out.println(s);

}

}

泛型修饰方法:

如代码所示,返回值前的 不能省略,否则就编程了泛型类中的普通方法,而不省略,则是泛型方法。

泛型方法在方法调用时根据传入的参数类型确定类型。

//泛型类

public class Generics {

private T arg;

//泛型类的普通方法

public String f(T arg) {

return arg.toString();

}

//泛型方法

private static K genericsType(K t)

{

return t;

}

public static void main(String[] args) {

Generics generics = new Generics();

String s = generics.f("111");

System.out.println(s);

Generics.genericsType(new Integer(1));

}

}

通配符:

那么,还有剩下的问题,我想更方便的使用这个类,既要传入Integer,也要传入String,如何处理呢。

如下这样会报错:

public class Generics {

private T arg;

private ArrayList arraylist;

public String f(T arg) {

return arg.toString();

}

private static K genericsType(K t)

{

return t;

}

public static void main(String[] args) {

Generics generics = new Generics();

String s = generics.f("111");

System.out.println(s);

Generics.genericsType(new Integer(1));

generics.arraylist=new ArrayList();

//报错,因为已经匹配了String

generics.arraylist=new ArrayList();//Type mismatch: cannot convert from ArrayList to ArrayList

}

}

而使用通配符?后,就可以做到:

public class Generics {

private T arg;

//使用通配符?

private ArrayList> arraylist;

public String f(T arg) {

return arg.toString();

}

private static K genericsType(K t)

{

return t;

}

public static void main(String[] args) {

Generics generics = new Generics();

String s = generics.f("111");

System.out.println(s);

Generics.genericsType(new Integer(1));

generics.arraylist=new ArrayList();

generics.arraylist=new ArrayList();

}

}

通配符的上下界:

这个概念也很好理解,当使用通配符时, extends Generics> 表示某种特定类型 ( Generics或者其子类 ) 的泛型, super Generics>示某种特定类型 ( Generics或者其超类 ) 的泛型。因为泛型的擦除是有上界的,如果直接使用?,那么有些不关联的类,只能使用到Object的方法,因为编译器只能确定该类是Object的子类。

而使用了 extends Generics>之后,所有的Generics类的方法,这个泛型均能使用。 extends Generics>这种形式在很多场景中被广泛使用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值