zoukankan      html  css  js  c++  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);
        }
    }

  • 相关阅读:
    项目中openlayer中使用,完整解决方案(数据库矢量数据,动态更新,分层,编辑)
    openlayer
    关于splitViewController自己的总结....
    GIS底层开发总结
    判断联网 phone
    nsdate 前一天 后一天
    ObjectiveC 字符处理函数 全 substring indexof
    oracle
    Windows Xp上跑IIS5.1x 用户访问过多出错
    Jquery中替换节点的方法replaceWith()和replaceAll()
  • 原文地址:https://www.cnblogs.com/zhangmingda/p/14645714.html
Copyright © 2011-2022 走看看