泛型的深入研究

来源:互联网 发布:嵌入式与人工智能关系 编辑:程序博客网 时间:2024/06/18 15:10

一 泛型定义

        允许在定义类、接口、方法时指定类型形参,这个类型形参在将在声明变量、创建对象、调用方法时时动态确定(即传入实际的类型参数,也可称为类型实参)。JDK1.5改写了集合框架中的全部接口和类,为这些接口、类增加了泛型支持,从而可以在声明集合变量、创建集合对象时传入类型实参。

 

二 泛型实质

        允许在定义接口、类时声明类型形参,类型形参在整个接口,类体内可当成类型使用,几乎所有可使用普通类型的地方都可以使用这种类型形参。例如:使用List类型时,如果为E形参传入String类型的实参,则产生一个新的类型:List<String>类型,可以把List<String>想象成E被全部替换成String的特殊List子接口。

 

三 类的泛型声明

1 代码示例

public class Apple<T>{// 使用T类型形参定义实例变量private T info;public Apple(){}// 下面方法中使用T类型形参来定义构造器public Apple(T info){this.info = info;}public void setInfo(T info){this.info = info;}public T getInfo(){return this.info;}public static void main(String[] args){// 由于传给T形参的是String,所以构造器参数只能是StringApple<String> a1 = new Apple<>("苹果");System.out.println(a1.getInfo());// 由于传给T形参的是Double,所以构造器参数只能是Double或doubleApple<Double> a2 = new Apple<>(5.67);System.out.println(a2.getInfo());}}

2 运行结果

苹果

5.67

3 代码分析

上面程序在定义了一个带泛型声明Apple<T>类,使用Apple<T>类就可为T类型形参传入实际类型,这样就可以生成Apple<String>、Apple<Double>形式的多个逻辑子类(物理上并不存在)。

 

四 泛型类派生子类

1 当从泛型类派生子类的时,不能再包括类型形参。

   public class A extends Apple<T>{}  这种定义是错误的。

2 定义类、接口、方法时可以声明类型形参,但使用类型,接口,方法时应该为类型形参传入实际的类型。

   public class A extends Apple<String>{}  这种定义是正确的。

3 调用方法时必须为所有的数据传入值,但使用类、接口时,也可以不为类型形参传入实际的类型参数。

   public class A extends Apple{}  这种定义是正确的。

4 从泛型类派生子类举例——传入实际类型参数。

 

public class A1 extends Apple<String>{// 正确重写了父类的方法,返回值// 与父类Apple<String>的返回值完全相同public String getInfo(){return "子类" + super.getInfo();}/*// 下面方法是错误的,重写父类方法时返回值类型不一致public Object getInfo(){return "子类";}*/}

 

5 从泛型类派生子类举例——不传入实际类型参数。

public class A2 extends Apple{// 重写父类的方法public String getInfo(){// super.getInfo()方法返回值是Object类型,// 所以加toString()才返回String类型return super.getInfo().toString();}}

 

五 泛型的错误用法

1 不能在静态变量声明中使用类型形参。

   static T info; //错误的

2 不能在静态方法中使用类型形参。

   public static void bar(T msg)   //错误的

3 instanceof运算符后不能使用泛型。

   if(cs instanceof java.util.ArrayList<string>)        //错误的

0 0
原创粉丝点击