Java中的泛型简单入门

Java中的泛型


在Java的开发中可能会遇到在定义一个类的时候,类的类型是不确定的时候。因此像方法一样,定义一个类的形参,类似于方法中的变量参数,将原来定义的类的类型参数化,在调用的时候再传入具体的类型,例如:定义一个泛型类如下:

//定义泛型类
public class Generic<T>{
	
}

上面定义了一个泛型类Generic,此时只是进行了定义,在使用时才具体确定泛型类Generic的类型。另外Generic泛型类的类型为T,这个T并没有什么实际的含义,只是作为一个一个泛型的类型变量而已。Java中一些常见的泛型的类型变量:

泛型的类型变量意义
E元素(Element),多用于java集合框架
K关键字(Key),多用于Map集合
N数字(Number)
T类型(Type)
V值(Value),多用于Map集合

接着,我们对Generic泛型类进行扩展:

//定义泛型类
public class Generic<T> {
	
	//定义泛型变量
	T data;

	public T getData() {
		return data;
	}

	public void setData(T data) {
		this.data = data;
	}
	
	public static void main(String[] args) {
	
		Generic<String> gen = new Generic<String>();
		gen.setData("data为String类型!");
		System.out.println(gen.getData());
		
	}
	
}

泛型的继承

定义一个泛型父类(这里我们定义一个抽象的泛型类):

/**
 * 定义一个抽象的泛型类
 * @author WL20180723
 *
 */
public abstract class Generic1<T> {

	T name;
	
	public abstract void test(T t);
	
}

再定义一个子类继承Generic1泛型类:

/**
 * 子类为具体的类
 * @author WL20180723
 *
 */
public class Child1 extends Generic1<String> {

	int name;
	
	public void test(String t) {
		this.name= t;
	}

}

Child1继承Generic1泛型类,并且在继承后指定了Generic1泛型类的具体类型为String类型,父类中的属性data也随着变成了String类型,子类Child1还有自己定义的name属性。
如果子类也为泛型类,类型在使用时确定(Child2<T> extends Generic1<T>):

/**
 * 
 * 子类为泛型类,类型在使用时确定
 * @author WL20180723
 *
 */
public class Child2<T, T1> extends Generic1<T> {
	
	T1 name
	public void test(T t) {
	}

}

此时的子类中的方法test()的参数类型随父类中的方法而定,且子类的泛型可以多余父类中的泛型。
若子类为泛型,父类不指定类型:

/**
 * 子类为泛型类,父类不指定类型
 * @author WL20180723
 *
 * @param <T>
 * @param <T1>
 * @param <T2>
 */
public class Child3<T, T1, T2> extends Generic1 {

	T1 name;
	
	public void test(Object t) {
		
	}

}

此时,子类中的方法的参数类型,统一使用Object代替。
还有一种,子类不指定类型,父类也不指定类型:

/**
 * 子类和父类都不指定类型
 * @author WL20180723
 *
 */
public class Child4 extends Generic1 {

	int name;
	
	public void test(Object t) {
		
	}

}

这种声明方式导致的结果就是子类中的方法的参数类型也统一由Object代替。

泛型接口

首先定义一个父类泛型接口:

/**
 * 定义泛型接口
 * @author WL20180723
 *
 * @param <T>
 */
public interface FatherInterface<T> {

	public void test(T t);
	
}

声明一个子类,子类实现父类接口时,父类指定具体类型:

/**
 * 声明子类,父类指定具体类型
 * @author WL20180723
 *
 */
public class ChildInterface1 implements FatherInterface<Integer> {

	public void test(Integer t) {
		
	}

}

在声明一个泛型接口的子类时,如果父类指定了类的具体类型(如在本例中为:FatherInterface<Integer>),子类中的方法中的参数类型跟随父类的具体类型。
如果声明子类,子类和父类都不指定具体类型,如下代码:

/**
 * 声明子类,都不指定具体类型
 * @author WL20180723
 *
 */
public class ChildInterface2 implements FatherInterface {

	public void test(Object t) {
		
	}

}

此时,子类类中的方法中的参数类型,统一使用Object代替。
若子类使用泛型,父类擦除(即父类不指定据类类型,也不使用泛型)如下代码:

/**
 * 子类使用泛型,父类擦除
 * @author WL20180723
 *
 * @param <T>
 */
public class ChildInterface3<T> implements FatherInterface {

	public void test(Object t) {
		
	}

}

此时,和上个例子一样,子类中的方法中的参数类型,统一使用Object代替。
当然,子类泛型个数也可以多于父类泛型个数,具体代码如下所示:

/**
 * 子类使用泛型>父类泛型
 * @author WL20180723
 *
 * @param <T>
 */
public class ChildInterface3<T, T1> implements FatherInterface<T> {

	public void test(T t) {
		
	}

}

但是父类使用泛型,而子类擦除时,和继承抽象类的泛型类一样,会出现编译错误!!!
在Java泛型中'?'也有使用,用来代表泛型的类型不确定,在使用时确定类型。注意:'?'只能在声明一个对象和方法中使用,不能在声明类的时候使用如:

Student<?> s = new Student<String>();public static void test(Student<?> s) {}public class Student<?> {}

关于'?'还有一些要注意的如下代码(省略了另外定义的两个类People和Animal,People继承了Animal):

/**
 * ?类型不确定,使用时确定类型
 * ?:在声明类型或者方法时使用,不能在声明类或者使用时使用
 * 没有泛型数组
 * @author WL20180723
 *
 * @param <T>
 */
public class Student<T> {

	T score;
	
	public static void main(String[] args) {
	
		Student<?> s = new Student<String>();
		test(new Student<Integer>());
		test2(new Student<People>());
//		test3(new Student<People>());//泛型没有多态
				
		Integer[] arr = new Integer[10];
//		Student<String>[] arr2 = new Student<String>[10];//不能创建泛型数组
		Student<?>[] arr2 = new Student[10];
		
	}
	
	public static void test(Student<?> s) {
	}
	
	public static void test2(Student<? extends Animal> s) {	
	}
	
	public static void test3(Student<Animal> s) {
	}
	 
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值