//泛型,java的参数化类型,泛型这个东西,说白了就是型参,也就是说类型本身可以作为参数来对类的类型做辅助说明。
//泛型,为了让集合能够记住其元素的数据类型
import java.util.ArrayList;
import java.util.List;
/**
* 定义了泛型就省去很多类型转换的代码了。
*/
public class GenericVariable {
public static void main(String[] args) {
List list = new ArrayList();//创建一个List集合
list.add("abc");//往集合里添加字符串
list.add("abcd");
list.add("abcde");
list.add("abcdef");
List<String> lx = list;//创建只保存字符串的集合lx,注意此时lx不是一般的集合,而是一个字符串类型的集合
//List是一个带类型参数(String)的泛型接口
String s1 = lx.get(0);//从集合lx里取出一个赋值给s1(前面已经定义lx只装字符串,所以这里不需要强制转换)
String s2 = (String)list.get(0);//拿出集合list里的第一个内容并强制转换为字符串
for (String str : lx) {
System.out.println("length of ["+str+"] is "+str.length());
}
List<Long> ly = list;//只能存放long型的集合ly
for (Long l : ly) {
System.out.println("l="+l);
}
}
}
public class GenericMethod {
protected Object foo;
public <T> T getFoo(){//使用泛型,T类型作为方法的返回类型
return (T)foo;
}
public <T> void setFoo(T foo){
this.foo = foo;
}
public static void main(String[] args) {
GenericMethod c = new GenericMethod();
String str = "abc";
c.<String>setFoo(str);//这里String作为实参传给形参T调用setFoo方法
String strx = c.<String>getFoo();
System.out.println("foo1="+c.getFoo());
System.out.println("-----------------------");
GenericMethod cx = new GenericMethod();
Long l = 123l;
cx.setFoo(l);//l是long型传给setFoo,相当于实参是long型传给形参T
System.out.println("foo2="+cx.getFoo());
System.out.println("-----------------------");
}
}
/*
* 不能在静态Field中使用类型形参,例如static T info;是错误的
* (存在疑问)不能再静态方法声明中使用类型形参,例如public static void bar(T msg){}也是错误的
* */
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
public class GenericClass<T> {//指定接口时指定了一个类型形参,该形参名为T
protected T foo;//T类型的变量
public T getFoo(){//返回T类型的方法
return foo;
}
public void setFoo(T foo){
this.foo = foo;
}
public void genericInfo(){
Type genericSuperclass = getClass().getGenericSuperclass();
TypeVariable[] vars = getClass().getSuperclass().getTypeParameters();
System.out.println("TypeParameter="+vars[0]);
Class<?> typeOfT =(Class<?>) ((ParameterizedType)genericSuperclass).getActualTypeArguments()[0];
System.out.println("type of T="+typeOfT.getName());
}
static class SubGenericClass extends GenericClass<Integer>{
}
public static void main(String[] args) {
GenericClass<String> c = new GenericClass<String>();
//这里可以写成GenericClass<String> c = new GenericClass<>();这属于泛型的菱形语法
String str = "abc";
c.setFoo(str);//这里将实参String型的str赋值给形参T类型的foo
String s = c.getFoo();//这里返回的T类型被String类型的变量s接受
System.out.println("foo1="+c.getFoo());
System.out.println("-----------------------");
GenericClass cx = new GenericClass<Long>();//等号左边的<Long>被省略了
Long l = 123l;
cx.setFoo(l);
System.out.println("foo2="+cx.getFoo());
System.out.println("-----------------------");
//下面的代码合理吗?运行一下看看。然后理解一下所谓类型擦除
GenericClass cxx = new GenericClass<Long>();
cxx.setFoo(str);//cxx是Long型,str这里是String型,Long型在这里应该被擦除了
System.out.println("foo3="+cxx.getFoo());
System.out.println("-----------------------");
//简单了解一下
SubGenericClass sc = new SubGenericClass();
sc.genericInfo();
System.out.println("-----------------------");
}
}