Java泛型(Generics)是JDK5开始引入的一个新特性,允许在定义类和接口的时候使用类型参数(Type Parameter)。声明的类型参数在使用时用具体的类型来替换,现在泛型最主要的应用是在JDK5中的新集合类框架中,Map, List均有用到。其中的优点不言而喻,我们可以横向扩展更多的类,缺点呢,其实也就是他的优点,因为这需要我们在使用泛型类的时候,要很清楚自己的代码目地,不能使用错误的类型。
最基本的泛型类
复制代码 代码如下:
package com.garinzhang.javabase.generic.e1;
public class Point
private T var;
public T getVar() {
return var;
}
public void setVar(T var) {
this.var = var;
}
}
package com.garinzhang.javabase.generic.e1;
public class GenericExample {
public static void main(String[] args) {
Point
p.setVar("coder");
System.out.println(p.getVar());
}
}
多个泛型类型
复制代码 代码如下:
package com.garinzhang.javabase.generic.e2;
public class Notepad
private T key;
private S value;
public T getKey() {
return this.key;
}
public S getValue() {
return this.value;
}
public void setKey(T key) {
this.key = key;
}
public void setValue(S value) {
this.value = value;
}
}
package com.garinzhang.javabase.generic.e2;
public class GenericExample {
public static void main(String[] args) {
Notepad
p.setKey("coder");
p.setValue(99999);
System.out.println("key: " + p.getKey());
System.out.println("value: " + p.getValue());
}
}
在方法参数中使用通配符"?"
复制代码 代码如下:
package com.garinzhang.javabase.generic.e3;
public class Info
private T key;
public T getKey() {
return this.key;
}
public void setKey(T key) {
this.key = key;
}
@Override
public String toString() {
return this.key.toString();
}
}
package com.garinzhang.javabase.generic.e3;
public class GenericExample {
public static void main(String[] args) {
Info
i.setKey("coder");
fun(i);
Info
j.setKey(9999);
fun(j);
}
public static void fun(Info> temp) {
System.out.println("Content: " + temp);
}
}
向上转型失败
复制代码 代码如下:
package com.garinzhang.javabase.generic.e4;
public class Info
private T key;
public T getKey() {
return this.key;
}
public void setKey(T key) {
this.key = key;
}
@Override
public String toString() {
return this.key.toString();
}
}
package com.garinzhang.javabase.generic.e4;
public class GenericExample {
public static void main(String[] args) {
Info
Info
// 编译错误"Type mismatch: cannot convert from Info
// 向上转型失败,String -> Object
// objEg = strEg;
}
}
泛型在接口中的使用
复制代码 代码如下:
package com.garinzhang.javabase.generic.e5;
interface Info
public T getVar();
}
package com.garinzhang.javabase.generic.e5;
public class InfoImpl
private T var;
public InfoImpl(T var) {
this.setVar(var);
}
public void setVar(T var) {
this.var = var;
}
public T getVar() {
return this.var;
}
}
package com.garinzhang.javabase.generic.e5;
public class InfoImpl1 implements Info
private String var;
public InfoImpl1(String var) {
this.setVar(var);
}
public void setVar(String var) {
this.var = var;
}
public String getVar() {
return this.var;
}
}
package com.garinzhang.javabase.generic.e5;
public class GenericExample {
public static void main(String[] args) {
Info
System.out.println("Content: " + strEg.getVar());
Info
System.out.println("Content: " + strEg1.getVar());
}
}
通配符和extends, super的使用
复制代码 代码如下:
package com.garinzhang.javabase.generic.e6;
public class Info
private T key;
public T getKey() {
return this.key;
}
public void setKey(T key) {
this.key = key;
}
@Override
public String toString() {
return this.key.toString();
}
}
package com.garinzhang.javabase.generic.e6;
public class GenericExample {
public static void main(String[] args) {
Info
strEg.setKey("coder");
// 编译报错"The method fun(Info extends Number>) in the type GenericExample is not applicable for the arguments (Info
// upTypeLimit(i);
// 使用Integer,Number类型均可以
Info
intEg.setKey(9999);
upTypeLimit(intEg);
// 编译报错"The method downTypeLimit(Info super String>) in the type GenericExample is not applicable for the arguments (Info
// downTypeLimit(intEg);
// 由于使用的是super,downTypeLimit只能接收String本身和Object
// 查看了String的继承关系,没有继承其他类,只有Object
downTypeLimit(strEg);
Info
objEg.setKey(999);
downTypeLimit(objEg);
}
public static void upTypeLimit(Info extends Number> temp) {
System.out.println("Content: " + temp);
}
public static void downTypeLimit(Info super String> temp) {
System.out.println("Content: " + temp);
}
}
方法泛型,方法里面多个泛型
复制代码 代码如下:
package com.garinzhang.javabase.generic.e7;
public class Info {
public
System.out.println(s.toString());
return t;
}
}
package com.garinzhang.javabase.generic.e7;
public class GenericExample {
public static void main(String[] args) {
Info info = new Info();
String str = info.fun("coder", "print second generic param");
System.out.println(str);
int i = info.fun(30, "print second param again");
System.out.println(i);
}
}
方法中传入或返回的泛型类型由调用方法时所设置的参数类型决定
复制代码 代码如下:
package com.garinzhang.javabase.generic.e8;
public class Info
private T var;
public T getVar() {
return this.var;
}
public void setVar(T var) {
this.var = var;
}
@Override
public String toString() {
return this.var.toString();
}
}
package com.garinzhang.javabase.generic.e8;
public class GenericExample {
public static void main(String[] args) {
Info
System.out.println(intEg.getVar());
}
public static
Info
temp.setVar(param);
return temp;
}
}
让方法中传入两个参数类型保持一致
复制代码 代码如下:
package com.garinzhang.javabase.generic.e9;
public class Info
private T var;
public T getVar() {
return this.var;
}
public void setVar(T var) {
this.var = var;
}
@Override
public String toString() {
return this.var.toString();
}
}
package com.garinzhang.javabase.generic.e9;
public class GenericExample {
public static void main(String[] args) {
Info
i1.setVar("Hello");
Info
i2.setVar("Coder");
Info
i3.setVar(999);
add(i1, i2);
//编译错误"The method add(Info
// add(i1, i3);
}
public static
System.out.println(i1.getVar() + ":" + i2.getVar());
}
}
泛型,可变参数,类似于javascript里的Arguments对象
复制代码 代码如下:
package com.garinzhang.javabase.generic.e10;
public class GenericExample {
public static void main(String[] args) {
Integer i[] = fun(1, 2, 3, 4, 5, 6);
fun2(i);
}
public static
return arg;
}
public static
System.out.println("generic array: ");
for(T t : param) {
System.out.println(t + " ,");
}
}
}
泛型嵌套:使用泛型类做为参数;根据返回值类型确定返回值
复制代码 代码如下:
package com.garinzhang.javabase.generic.e11;
public class Info
private T var;
private V value;
public T getVar() {
return this.var;
}
public void setVar(T var) {
this.var = var;
}
public V getValue(){
return this.value;
}
public void setValue(V value) {
this.value = value;
}
@Override
public String toString() {
return this.var.toString();
}
}
package com.garinzhang.javabase.generic.e11;
public class Demo {
private S info;
public Demo(S info) {
this.setInfo(info);
}
public void setInfo(S info) {
this.info = info;
}
public S getInfo() {
return this.info;
}
}
package com.garinzhang.javabase.generic.e11;
import java.util.List;
import com.google.common.collect.Lists;
public class GenericExample {
public static void main(String[] args) {
Demo
Info
i = new Info
i.setVar("Coder");
i.setValue(999);
d = new Demo
System.out.println("Content: " + d.getInfo().getVar());
System.out.println("Content: " + d.getInfo().getValue());
System.out.println(query(1, 2, 3, 4, 5).toString()); // [1, 2, 3, 4, 5]
// 警告"Type safety: A generic array of Object&Comparable>&Serializable is created for a varargs parameter"
System.out.println(query(1, 2, 3, "StringType").toString()); // [1, 2, 3, StringType]
System.out.println(query("I ", "am ", "a ", "coder").toString());// [I , am , a , coder]
List
System.out.println(list.toString()); // [I , am , a , coder]
}
public static
// https://github.com/exitsoft/exit-web-framework/commit/1d2f1098a2a4b6abab175b793e2308aa8bd0ea16.
// import com.google.common.collect.Lists;
//
//
// guava
//
//
return Lists.newArrayList(elements);
}
}



