Java教程

java 数据类型:<泛型>在方法中和在构造器中的应用

本文主要是介绍java 数据类型:<泛型>在方法中和在构造器中的应用,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

背景:

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>编译报错
    }
}

Java8改进泛型推断判断

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();
    }
}

擦除:

在严格的泛型代码里,带泛型声明的类总应该带着类型参数。 但为了与老的 Java 代码保持一致,也允许在使用带泛型声明的类时不指定实际的类型。如果没有为这个泛型类指定实际的类型,此时被称为 raw type (原始类型),默认是声明该泛型形参时指定的第一个上限类型。
/**
 * @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);
    }
}

 

 

这篇关于java 数据类型:<泛型>在方法中和在构造器中的应用的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!