简介
泛型是程序设计语言的一种特性。允许程序员在强类型程序设计语言中编写代码时定义一些可变部分,那些部分在使用前必须作出指明。
泛型的使用
先将之前写过的栈转换为泛型栈
/**
* 泛型栈
* @author 14831
*
* @param <T>
*/
public class TStack<T> {
/**
* 泛型数组
*/
private T[] data = null;
/**
* 栈顶
*/
private int top;
/**
* 栈的长度
*/
private int length;
/**
* 空构造函数
*/
public TStack() {
this(10);
}
/**
* 有参构造函数
* @param i 栈的长度
*/
public TStack(int i)
{
//data = new T[i]; × 错误
length = i;
//通过将object数组强转为泛型数组的方式创造泛型数组
data = (T[]) new Object[length];
//栈顶初始化
top = 0;
}
/**
* 入栈
* @param val
*/
public void push(T val)
{
if(top>=length)
{
return;
}
this.data[top++] = val;
}
/**
* 出栈
* @return 数据
*/
public T pop()
{
if(top==0)
{
return null;
}
return this.data[--top];
}
/**
* 获得栈顶元素
* @return 数据
*/
public T getTop()
{ if(top==0)
{
return null;
}
return this.data[top-1];
}
public static void main(String[] args) {
TStack<Integer> a = new TStack<Integer>(10);
for (int i = 0; i < a.length; i++) {
a.push(i);
}
for (int i = 0; i < a.length; i++) {
System.out.print(a.pop()+" ");
}
}
}
运行结果9 8 7 6 5 4 3 2 1 0
此泛型栈可以根据类型存放不同的对象。
泛型的意义
<T>
T是一个类型占位符,它所占的位置就是当你确定这个泛型的类型之后,系统进行自动类型检查和自动类型转换所确定的类型
a.会对类型进行自动检查
b.会进行自动类型转换
泛型的坑
1.不能new泛型类型的数组
正确的方式是这种
data = (T[]) new Object[length];
2.不能new泛型的对象
因为T
只是在编译的时候进行类型的检查
3.不能得到泛型类型的对象数组
TStack<Integer>[] a = new TStack<Integer>[10]; ×
错误
因为泛型本质是向上擦除成Object,所以其数组相当于Object数组,而且其没有泛型的约束,所以会产生矛盾。
如TStack<Integer>[] a = new TStack<Integer>[10];
===Object[] a = new Object[10];
然后就可以给a赋任何值,所以其泛型也就没有了意义,此点和泛型的作用(编译类型检查)相矛盾
4.简单类型不能作为泛型的参数
如int,double,float等
5.在Static方法中,不能用泛型类型的参数
public static T getT()
{
return null;
}
错误,其正确方式为
public static<T> T getT()
{
return null;
}
只有在static后面加上<T>
编译器才能通过
泛型的上界
泛型的实质是类型擦除,擦除的最终目标是Object,当我们给泛型设定上界以后,泛型就会被擦除成你所指定的上界。其声明方式为
<T extends superClass>
这样就有了无限可能。
我们可以写一个FindMax函数,可以查找所有实现Comparable
接口的类的最大值.
/**
* 寻找最大值
* @author 焦焱
*
* @param <T> Comparable<T>擦除到Comparable<T>
*/
class MyMath<T extends Comparable<T>>
{
/**
* 寻找最大值
* @param array 数组
* @return 最大的数据
*/
public static<T extends Comparable<T>> T finMaxVal(T[] array)
{
T maxVal = array[0];
for (int i = 1; i < array.length; i++) {
if(maxVal.compareTo(array[i])<0)
{
maxVal = array[i];
}
}
return maxVal;
}
}
测试
Integer[] a = {12,3125,435,64000,67};
MyMath<Integer> a1 = new MyMath<Integer>();
System.out.println(a1.finMaxVal(a));
Integer内部已经实现了Comparable接口。
结果64000