泛型类定义与使用
-
定义泛型
//定义 class Point<T>{// 此处可以随便写标识符号 private T x ; private T y ; };
-
类中使用泛型
//定义变量 private T x ; //作为返回值 public T getX(){ return x ; } //作为参数 public void setX(T x){ this.x = x ; }
-
使用泛型类
//IntegerPoint使用 Point<Integer> p = new Point<Integer>() ; p.setX(new Integer(100)) ; System.out.println(p.getX());
多泛型变量定义及字母规范
-
多泛型变量定义
class MorePoint<T,U>{ }
改写Point 类,使其具有两个泛型
class MorePoint<T,U> { private T x; private T y; private U name; public void setX(T x) { this.x = x; } public T getX() { return this.x; } ………… public void setName(U name){ this.name = name; } public U getName() { return this.name; }
-
字母规范,指定泛型时可食用下述字母规范,当然不是硬性要求,只是为了提高可读性。
E — Element,常用在java Collection里,如:List<E>,Iterator<E>,Set<E> K,V — Key,Value,代表Map的键值对 N — Number,数字 T — Type,类型,如String,Integer等等
泛型接口定义及使用
-
定义泛型接口
interface Info<T>{ // 在接口上定义泛型 public T getVar() ; // 定义抽象方法,抽象方法的返回值就是泛型类型 public void setVar(T x); }
-
非泛型类使用
class InfoImpl implements Info<String>{ // 定义泛型接口的子类 private String var ; // 定义属性 public InfoImpl(String var){ // 通过构造方法设置属性内容 this.setVar(var) ; } @Override public void setVar(String var){ this.var = var ; } @Override public String getVar(){ return this.var ; } } public class Demo{ public void main(String arsg[]){ InfoImpl i = new InfoImpl("hello"); System.out.println(i.getVar()) ; } };
InfoImpl类实现接口时,将接口的泛型指明为String类型,因此所生成的setVar()和getVar()方法中使用到泛型的地方都替换成了String。
-
泛型类使用
如果实现类也有泛型怎么办?
class InfoImpl<T> implements Info<T>{ // 定义泛型接口的子类 private T var ; // 定义属性 public InfoImpl(T var){ // 通过构造方法设置属性内容 this.setVar(var) ; } public void setVar(T var){ this.var = var ; } public T getVar(){ return this.var ; } } public class Demo{ public static void main(String arsg[]){ InfoImpl<String> i = new InfoImpl<String>("hello"); System.out.println(i.getVar()) ; } };
这里实现类
InfoImpl
的泛型跟所要实现的接口泛型类型一致,如果InfoImpl
只有一个泛型,那么如果不跟Info
一致的话,在实现Info
接口的方法时,会找不到T这个变量类型。
如果InfoImpl
中除了接口中的两个方法还需要添加别的方法的话,那么还可以构造一个多泛型变量的类,如下:class InfoImpl<T,U,P> implements Info<T> { private U u; private T t; private P p; public InfoImpl(U u,P p){ this.u = u; this.p = p; } @Override public T getVar() { return t; } @Override public void setVar(T x) { this.t = x; } public U getU(){ return u; } public P getP(){ return p; } } public class Test{ public static void main(String[] args) { InfoImpl<String,Integer,Float> info = new InfoImpl<>(2,2.0f); info.setVar("hello"); System.out.println("U:" + info.getU()); System.out.println("P:" + info.getP()); System.out.println("var:" + info.getVar()); } }
这里`InfoImpl`类中`setVar()`和`getVar()`所使用的泛型变量跟接口的变量类型一样,另外还加了两个泛型变量,在方法定义的时候使用到了。构造方法里用到了第二个和第三个泛型变量,测试的结果也证明了确实将数值传进去了。
### 泛型函数的定义与使用
泛型函数的定义不过是在返回类型前加上了泛型标记,表明这是一个泛型函数,其他并没有什么区别。
class FMethod{
public static <T> String testMethod(T t){
return "T---" + t.toString();
}
public static <T> T testReturnT(T t){
return t;
}
}
public class Test{
public static void main(String[] args) {
System.out.println(FMethod.testMethod("hello"));
System.out.println(FMethod.<String>testMethod("hello"));
System.out.println(FMethod.testReturnT("helloReturn"));
}
}
泛型函数的使用方式有这两种:
FMethod.testMethod("hello"));
FMethod.<String>testMethod("hello")
- 第一种:隐式传递了泛型类型。
- 第二种:显示将泛型类型设置为String,直接能看出来这是一个泛型函数。
**第一种方式虽然写起来十分方便,但是隐藏泛型类型,并不能一眼判断出这到底是泛型函数还是普通函数。并且,在参数传递出错时,并不会有警告,第二种显示设置泛型类型为String的话,如果传递的参数是int类型,那么会直接报错。**
![error.png](http://upload-images.jianshu.io/upload_images/4162886-9a8814c29d1bd8f9.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
### 参考资料
[夯实JAVA基本之一 —— 泛型详解(1):基本使用](http://blog.csdn.net/harvic880925/article/details/49872903)