zoukankan      html  css  js  c++  java
  • JAVA的泛型

    一、JAVA的泛型(泛型就是语法糖)

    1、泛型类

    ①只能用在非静态成员变量和非静态成员方法上

    ②只能代替引用变量

    class Student<T>{
        T name;
        public T getName() {
            return name;
        }
    }

    2、泛型接口

    ①只能用在抽象方法上,不能用在常量上

    interface Human<T>{
        T compareTo(T t);
    }

    3、泛型方法(静态方法和非静态方法两者皆可以用)

    class Method{
        public static <T> void show(T t) {
            
        }
    }
    class Method2{
        public static <T extends Cloneable> void show(T t) {
            
        }
    }

    4、泛型继承(四种情况 )

    //泛型父类(抽象方法和接口和父类都一样)
    abstract class Father<T1,T2>{
        T1 age;
        abstract void test(T2 arg); 
    }
    //①不指定类shi于:Father<Object,Object>
    class Son1 extends Father{
        @Override
        void test(Object arg) {
            // TODO Auto-generated method stub        
        }        
    }
    class Son11<A,B> extends Father{
        @Override
        void test(Object arg) {
            // TODO Auto-generated method stub        
        }    
    }
    
    //②指定具体类型
    class Son2 extends Father<Integer,String>{
        @Override
        void test(String arg) {
            // TODO Auto-generated method stub        
        }    
    }
    class Son22<A,B> extends Father<Integer,String>{
        @Override
        void test(String arg) {
            // TODO Auto-generated method stub        
        }    
    }
    
    //③部分保留,泛型子类
    class Son3<T1> extends Father<T1,String>{
        @Override
        void test(String arg) {
            // TODO Auto-generated method stub        
        }    
    }
    class Son33<T1,A,B> extends Father<T1,String>{
        @Override
        void test(String arg) {
            // TODO Auto-generated method stub        
        }    
    }
    
    //④完全保留,泛型子类
    class Son4<T1,T2> extends Father<T1,T2>{
        @Override
        void test(T2 arg) {
            // TODO Auto-generated method stub        
        }    
    }
    class Son44<T1,T2,A,B> extends Father<T1,T2>{
        @Override
        void test(T2 arg) {
            // TODO Auto-generated method stub        
        }    
    }

    5、泛型擦除(使用、实现、继承的时候不指定类型)

    public class App 
    {
        public static void main( String[] args )
        {
            //第一种情况(泛型的擦除)
            Teacher teacheer = new Teacher();
            Object obj = teacheer.getName();
            //第二种情况(泛型的擦除)
            Teacher<String> teacher2 = new Teacher();
            //第三种情况(泛型的擦除)
            Teacher teacher3 = new Teacher<String>();
            //第四种情况,这种情况是有错误的(编译时错误)
            //Teacher<Object> teacher4 = new Teacher();
            //Teacher<String> teacher5 = teacher4;
        }
    }
    //泛型的擦除,使用、实现、继承不指定类型
    class Teacher<T>{
        T name;
        T getName() {
            return name;
        }
        void setName(T name) {
            this.name = name;
        }
    }

     6、泛型的嵌套

    public class Solution {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            Student<Double> s1 = new Student<Double>();
            s1.setScore((double) 100);
            Banji<Student<Double>> ssas = new Banji<Student<Double>>();
            ssas.setStu(s1);
            Double adasd = ssas.getStu().getScore();
            System.out.println(adasd);
        }
    
    }
    
    class Student<T> {
        T score;
    
        public T getScore() {
            return score;
        }
    
        public void setScore(T score) {
            this.score = score;
        }
    
    }
    
    class Banji<R> {
        R stu;
    
        public R getStu() {
            return stu;
        }
    
        public void setStu(R stu) {
            this.stu = stu;
        }
    
    }

    7、泛型需要注意的地方

    ①泛型没有多态
    ②泛型没有数组
    ③泛型不能使用静态属性
    ④泛型不能使用基本数据类型

    ⑤静态方法中不能访问类的泛型

    ⑥catch语句中不能使用泛型catch(T e){}这样子是错误的

    public class DuoTai {
    
        public static void main(String[] args) {
            //泛型没有多态
            Object object = new String();
         Object[] strs = new String[10];//数组是可以的
    //List<Object> object1 = new ArrayList<String>();错误 //泛型没有数组 //List<Object>[] object2 = new ArrayList<Object>[10];错误 //jdk1.7关于泛型的简化 List<Object> object3 = new ArrayList<>(); //相较于以前的List<Object> object3 = new ArrayList<Object>(); } } class Fruit { } class Apple extends Fruit { } class Pear extends Fruit { } class FushiApple extends Apple { }

    二、JAVA的泛型通配符:?(super和extends)

    List<?>是所有List<Object>,List<String>,List<Integer>...的父类

    List<?>这样的集合是可以读取的(读取出来的元素类型是Object),写入是不允许的,只能写入null(这个要结合这种式子只能写在等号左边,它不知道等号右边传给它的实际的集合是什么类型的)

    1、泛型通配符(?)

    ①?通配符就是表示类型不确定

    ②只能用在(声明类型、方法参数)上也就是等号左边;不能用在定义泛型类上也就是等号右边

    ③不能用在定义泛型类泛型接口泛型方法上(就是不能放在定义泛型的尖括号里面)

    List<?> list = new ArrayList<String>();
    list = new ArrayList<Integer>();
    list = new ArrayList<Date>();

    2、泛型上限(? extends  xxx)(包含等于)

    ①一般用于限制某个操作
    ②不能使用在数据添加上面,一般用于数据读取

    ③List<?>等同于List<? extends Object>

    public class App 
    {
        public static void main( String[] args )
        {
            List<? extends Fruit> t1 = new ArrayList<Fruit>();
            test(t1);
            List<Fruit> t2 = new ArrayList<Fruit>();
            test(t2);
            List<Apple> t3 = new ArrayList<Apple>();
            test(t3);
            List<? extends Apple> t4 = new ArrayList<FushiApple>();
            test(t4);
            List<?> t5 = new ArrayList<Fruit>();
            //List<?>等同于List<? extends Object>
            //test(t5);错误
            
        }
        static void test(List<? extends Fruit> list) {
            //list.add(new Apple());错误
            list.add(null);
        }
        
    }
    class Fruit{
        
    }
    class Apple extends Fruit{
        
    }
    class Pear extends Fruit{
        
    }
    class FushiApple extends Apple{
        
    }
    class Test<T extends Fruit>{
        
    }

    3、泛型下限(? super  xxx)(包含等于)

    ①不能用于添加父类信息

    public class App {
        public static void main(String[] args) {
            List<Fruit> t1 = new ArrayList<Fruit>();
            show(t1);
            List<Apple> t2 = new ArrayList<Apple>();
            show(t2);
            List<Object> t3 = new ArrayList<Object>();
            show(t3);
            List<? super Apple> t4 = new ArrayList<Apple>();
            show(t4);
            List<? super Fruit> t5 = new ArrayList<Object>();
            show(t5);
            List<? super FushiApple> t6 = new ArrayList<Object>();
            //show(t6);错误
            List<?> list7 = new ArrayList<Object>();
            //show(t7);错误
        }
    
        static void show(List<? super Apple> list) {
            list.add(new Apple());
            list.add(new FushiApple());
            // 不能用于添加父类信息
            //list.add(new Fruit());
        }
    }
    
    class Fruit {
    
    }
    
    class Apple extends Fruit {
    
    }
    
    class Pear extends Fruit {
    
    }
    
    class FushiApple extends Apple {
    
    }

    4、图解

    假设给定的泛型类型为G,(如List<E>中的List),两个具体的泛型参数X、Y,当中Y是X的子类:

    • G<? extends Y> 是 G<? extends X>的子类型(如List<? extends Cat> 是 List<? extends Animal>的子类型)。
    • G<X> 是 G<? extends X>的子类型(如List<Animal> 是 List<? extends Animal>的子类型)
    • G<?> 与 G<? extends Object>等同,如List<?> 与List<? extends Objext>等同。

     Plate<? extends Fruit>Plate<Fruit>以及Plate<Apple>的基类。这种不能往里面存,只能取。

    Plate<? super Fruit>Plate<Fruit>的基类,但不是Plate<Apple>的基类。这种只能往里面存,不能取。要取也只能取在Object对象里。

    三、一个经典的实例:

    package org.eclipse.winery.repository;
    
    import java.util.ArrayList;
    import java.util.Collection;
    import java.util.List;
    
    public class Main2 {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            List<Obj> list = new ArrayList<Obj>();
            list.add(new Obj());
            List<?> list2 = list;
            list2.forEach((obj) -> System.out.println(((Obj) obj).name));
            Collection<?> list3 = list;
            list3.forEach((obj) -> System.out.println(((Obj) obj).name));
            Collection<Obj> list4 = list;
            list4.forEach((obj) -> System.out.println(((Obj) obj).name));
    
        }
    
        private static class Obj {
            public String name = "Soar up into the sky with one start!";
        }
    }

    从这里我们看出了Collection<Obj>是List<Obj>的父类

    四、泛型的静态方法

    静态方法有一种情况需要注意一下,那就是在类中的静态方法使用泛型:静态方法无法访问类上定义的泛型;如果静态方法操作的引用数据类型不确定的时候,必须要将泛型定义在方法上。

    即:如果静态方法要使用泛型的话,必须将静态方法也定义成泛型方法 。

    五、JAVA的extends在泛型中的扩展

    public static <T extends Comparable<T>> void sort(T[] arr) {
            
        }
  • 相关阅读:
    Javascript学习总结
    MVC和MVVM
    各大搜索引擎网址收录入口地址
    微软称IE9将更加出色 对手谷歌也能从中受益(图文)
    公安部:身份证丢失无需挂失 被冒用不担责 冒用身份证犯罪
    微软发布Mac 8版Messenger 支持视频会议(图)
    如何删除XP系统的NETWARE,改变登陆界面 火急!!XP系统登录界面由于netware造成的不能更改
    使用WebBrowser自动登录阿里妈妈网站
    微软发布IE9开发者预览版 不支持XP系统(图)
    ASP 0113 的错误的终极解决办法(三种)
  • 原文地址:https://www.cnblogs.com/erdanyang/p/10304215.html
Copyright © 2011-2022 走看看