public class Test1<R,T> { //声明入参和返回值不一样类型的方法,使用自己的泛型,尽管名字一样 public <R,T> R testMethod(T t){ System.out.println(t.getClass().getName()); R a = (R) t.getClass().getName(); System.out.println(a.getClass().getName()); return a; } //使用类的泛型 public void testMethod1(T t){ System.out.println(t.getClass().getName()); } //使用类的泛型 public R testMethod2(String a){ R b = (R)a; System.out.println(b); return b; }
public static void main(String[] args) { Test1<Integer,String> test1 = new Test1<>(); test1.testMethod1("3"); test1.testMethod2("4"); //java会进行强转但是报错了 // Byte name = test1.testMethod(100L); String name = test1.testMethod(100L); System.out.println(name); } }
所以如果非必要情况下类的泛型和方法的泛型不需要使用同一个字母。这样会好看的多。
1 2 3 4 5 6 7 8 9
public class Test1<T,R> {
public <K,V> K testMethod(V t){ return null; } public void testMethod1(T t){ } }
泛型接口
1 2 3 4 5 6
public interface Test1<T> {
public T testMethod(T t);
public void testMethod1(T t) }
实现类
1 2 3 4 5 6 7 8 9 10 11 12
public class Test2Impl implements Test2<String>{
@Override public String testMethod(String s) { return null; }
@Override public void testMethod1(String s) {
} }
泛型与可变参数
1 2 3 4 5 6 7 8 9 10 11 12
public class Test1 { public <T> void printMsg( T... args){ for(T t : args){ System.out.println("泛型测试 t is " + t+"class "+t.getClass().getName()); } }
public static void main(String[] args) { test1.printMsg("111",222,"aaaa","2323.4",55.55); } }
泛型上线边界
泛型也不是无限使用,像上面Byte类型的会报错,所以在泛型上也使用一些上下边界来处理。
1 2 3 4 5 6 7 8
class Base{}
class Sub extends Base{}
Sub sub = new Sub(); Base base = sub; List<Sub> lsub = new ArrayList<>(); List<Base> lbase = lsub;
public void testMethod( T t){ System.out.println(t.getClass().getName()); }
public static void main(String[] args) { Test3<Base> data = new Test3<>(); Sub sub = new Sub(); SubSon subSon = new SubSon(); Base base = new Base(); data.testMethod(base);//编译通过 data.testMethod(sub); //编译通过 data.testMethod(subSon);//编译通过 Test3<NoSub> data1 = new Test3<>();//编译不通过 }
想一下如果Test3<Base> data = new Test3<>();声明的是Sub,那么代码编译会是怎么样的。留个你去思考
<? super T>`被称作有下限的通配符。
1 2 3 4 5 6
public class Collections { public static <T> void copy(List<? super T> dest, List<? extends T> src) { for (int i = 0; i < src.size(); i++) dest.set(i, src.get(i)); } }