欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

泛型的深入研究

程序员文章站 2022-04-05 17:50:03
...

一 泛型定义

        允许在定义类、接口、方法时指定类型形参,这个类型形参在将在声明变量、创建对象、调用方法时时动态确定(即传入实际的类型参数,也可称为类型实参)。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,所以构造器参数只能是String
		Apple<String> a1 = new Apple<>("苹果");
		System.out.println(a1.getInfo());
		// 由于传给T形参的是Double,所以构造器参数只能是Double或double
		Apple<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>)        //错误的

相关标签: 泛型