背景:
Java不允许我们把对象放在一个未知的集合中。import java.util.ArrayList; import java.util.List; /** * @ClassName MethodTest * @projectName: object1 * @author: Zhangmingda * @description: 方法泛型的问题引出案例:当我们创建一个方法,数组中对象加到一个List集合中时, * Java不允许我们把对象放在一个未知数据类型的集合中。 * date: 2021/4/11. */ public class MethodTest { private static void arrayToList(Object[] objs, List<?> list) { for (Object obj : objs) { list.add(obj); //编译报错:因为Java不允许我们把对象放在一个未知数据类型的集合中。 } } public static void main(String[] args) { Object[] strArr = {"李一桐", "刘亦菲", "鞠婧祎"}; List<String> list = new ArrayList<>(); arrayToList(strArr, list); System.out.println(list); } }
为了解决这个问题,可以使用Java提供的泛型方法(Generic Method)。所谓泛型方法,就是在声明方法时定义一个或多个泛型形参。
修饰符 <T , S> 返回值类型 方法名(形参列表){ 方法体... }
import java.util.ArrayList; import java.util.List; /** * @ClassName MethodTest * @projectName: object1 * @author: Zhangmingda * @description: 方法泛型的问题引出案例:当我们创建一个方法,数组中对象加到一个List集合中时, * Java不允许我们把对象放在一个未知数据类型的集合中。 * date: 2021/4/11. */ public class MethodTest { private static <T> void arrayToList(T[] objs, List<T> list) { for (T obj : objs) { list.add(obj); //List<?> list编译报错:因为Java不允许我们把对象放在一个未知数据类型的集合List<?> list中。 } } public static void main(String[] args) { String[] strArr = {"李一桐", "刘亦菲", "鞠婧祎"}; List<String > list = new ArrayList<>(); arrayToList(strArr, list); System.out.println(list); //[李一桐, 刘亦菲, 鞠婧祎] } }
import java.util.ArrayList; import java.util.List; /** * @ClassName MethodTest2 * @projectName: object1 * @author: Zhangmingda * @description: XXX * date: 2021/4/11. */ public class MethodTest2 { private static <T,E>void printList(List<T> list, List<E> list1){ System.out.println(list); System.out.println(list1); } public static void main(String[] args) { List<String> list = new ArrayList<>(); list.add("张三"); list.add("李四"); list.add("王五"); List<Integer> list1 = new ArrayList<>(); list1.add(1); list1.add(2); list1.add(3); printList(list,list1); } }
/** * @ClassName InitTest * @projectName: object1 * @author: Zhangmingda * @description: XXX * date: 2021/4/11. */ public class InitTest { private static class Foo{ public <T> Foo(T t) { System.out.println(t); } } public static void main(String[] args) { Foo foo = new Foo(123); Foo foo1 = new Foo("张三"); Foo foo2 = new<String> Foo("张三"); Foo foo3 = new <String> Foo(12); // <String>编译报错 } }
public class InferTest { private static class A<T> { public static <E> A<E> test1() { System.out.println("test1"); return new A<>(); } public static <E> A<E> test2(E e, A<E> a) { System.out.println("test2"); return new A<>(); } public T head() { System.out.println("test3"); return null; } } public static void main(String[] args) { //下面两行代码相同 A<String> a1 = A.test1(); A<String> a2 = A.<String>test1(); // //下面两行代码相同 A.test2(56, A.test1()); // A.test2(56, A.<Integer>test1()); //下面代码如果用自动类型推断A.test1().head(),它会经过两次推断,最后就变成了不但能推断,因为我们自动类型推断,只能推断1次 String s = A.<String>test1().head(); } }
/** * @ClassName ErasureTest * @projectName: object1 * @author: Zhangmingda * @description: XXX * date: 2021/4/11. */ public class ErasureTest { private static class A<T extends Number>{ private T size; public A(T size) { this.size = size; } public T getSize() { return size; } } public static void main(String[] args) { A<Integer> a = new A<>(33); int size = a.getSize(); System.out.println(size); A a1 = a; //int size1 = a1.getSize(); // 这里size接收报错,a1实例化的时候没有显式的指定该泛型的类型,所以只能用顶级的Number去接收了 Number number = a1.getSize(); System.out.println(number); } }