• java 3y 泛型就这么简单


    泛型方法

    • 所有泛型方法声明都有一个类型参数声明部分(由尖括号分隔),该类型参数声明部分在方法返回类型之前(在下面例子中的T)。
    • 每一个类型参数声明部分包含一个或多个类型参数,参数间用逗号隔开。一个泛型参数,也被称为一个类型变量,是用于指定一个泛型类型名称的标识符。
    • 类型参数能被用来声明返回值类型,并且能作为泛型方法得到的实际参数类型的占位符。
    • 泛型方法体的声明和其他方法一样。注意类型参数只能代表引用型类型,不能是原始类型(像int,double,char的等)。
       
    //定义泛型方法, 类型参数声明部分在方法返回类型之前
    public <T> void show(T t) {
        System.out.println(t);
    }
    
    //多个类型参数
    public class testooo {
        public static <T, V> void s(T t, V v, int a) {
            System.out.println(t);
            System.out.println(v);
        }
    
        public static void main(String[] args) {
            testooo.s(1, 2, 3);
        }
    }
    

    泛型类是拥有泛型这个特性的类,它本质上还是一个Java类,那么它就可以被继承

    那它是怎么被继承的呢??这里分两种情况

    1. 子类明确泛型类的类型参数变量
    2. 子类不明确泛型类的类型参数变量
       

    子类明确泛型类的类型参数变量

    /*
        把泛型定义在接口上
     */
    public interface Inter<T> {
        public abstract void show(T t);
    
    }
    /**
     * 子类明确泛型类的类型参数变量:
     */
    
    public class InterImpl implements Inter<String> {
        @Override
        public void show(String s) {
            System.out.println(s);
    
        }
    }
    

    子类不明确泛型类的类型参数变量

    当子类不明确泛型类的类型参数变量时,外界使用子类的时候,也需要传递类型参数变量进来,在实现类上需要定义出类型参数变量
     

    /**
     * 子类不明确泛型类的类型参数变量:
     *      实现类也要定义出<T>类型的
     *
     */
    public class InterImpl<T> implements Inter<T> {
    
        @Override
        public void show(T t) {
            System.out.println(t);
    
        }
    }
    public static void main(String[] args) {
        //测试第一种情况
        //Inter<String> i = new InterImpl();
        //i.show("hello");
    
        //第二种情况测试
        Inter<String> ii = new InterImpl<>();
        ii.show("100");
    }
    

    1.实现类的要是重写父类的方法,返回值的类型是要和父类一样的
    2.类上声明的泛形只对非静态成员有效,这一点说明如下
     

    #1.泛型类中的静态方法不能使用类的泛型,而应该将该方法定义为泛型方法
    1.错误示范:
    
    class demo<T>{
        public static T show(T temp) {
            return temp;
        }
    }
    2.正确示范:
    
    class demo<T>{
        public static <T> T show(T temp) {
            return temp;
        }
    }
    3.原因:
    
       在java中泛型只是一个占位符,必须在传递类型后才能使用。就泛型类而言,类实例化时才能传递真正的类型参数,
    由于静态方法的加载先于类的实例化,也就是说类中的泛型还没有传递真正的类型参数时,静态方法就已经加载完成。
    显然,静态方法不能使用/访问泛型类中的泛型。
    
    这和静态方法不能调用普通方法/访问普通变量类似,都是因为静态申明与非静态申明的生命周期不同。
    
     
    
    #2.不能定义静态泛型变量
    1.原因:
    
    由于静态变量在java程序一运行时就已经被载入内存,而此时它的类型无法确定,而开辟空间必须知道类型,两者矛盾。
    ————————————————
    版权声明:本文为CSDN博主「SWEENEY_HE」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/SWEENEY_HE/article/details/88615836
    

       

    类型通配符

    public void test(List<Object> list){
       for(int i=0;i<list.size();i++){
           System.out.println(list.get(i));
       }
    }
    

    该test()方法只能遍历装载着Object的集合!!!
    泛型中的<Object>并不是像以前那样有继承关系的,也就是说List<Object>和List<String>是毫无关系的

     
    改为?

    public void test(List<?> list){
        for(int i=0;i<list.size();i++){
            System.out.println(list.get(i));
        }
    }
    

     
    ?号通配符表示可以匹配任意类型,任意的Java类都可以匹配…..
    现在非常值得注意的是,当我们使用?号通配符的时候:就只能调对象与类型无关的方法,不能调用对象与类型有关的方法。
    记住,只能调用与对象无关的方法,不能调用对象与类型有关的方法。
     

    设定通配符上限

    现在,我想接收一个List集合,它只能操作数字类型的元素【Float、Integer、Double、Byte等数字类型都行】,怎么做???
    我们学习了通配符,但是如果直接使用通配符的话,该集合就不是只能操作数字了。因此我们需要用到设定通配符上限 

    List<? extends Number>
    

    设定通配符下限

    //传递进来的只能是Type或Type的父类
    <? super Type>
    

    使用中

    • 大多时候,我们都可以使用泛型方法来代替通配符的
    • 如果参数之间的类型有依赖关系,或者返回值是与参数之间有依赖关系的。那么就使用泛型方法
    • 如果没有依赖关系的,就使用通配符,通配符会灵活一些.
       

    泛型擦除

    • 泛型是提供给javac编译器使用的,它用于限定集合的输入类型,让编译器在源代码级别上,即挡住向集合中插入非法数据。但编译器编译完带有泛形的java程序后,生成的class文件中将不再带有泛形信息,以此使程序运行效率不受到影响,这个过程称之为“擦除”。
    • JDK5提出了泛型这个概念,但是JDK5以前是没有泛型的。也就是泛型是需要兼容JDK5以下的集合的。
    • 当把带有泛型特性的集合赋值给老版本的集合时候,会把泛型给擦除了。
       
      值得注意的是:它保留的就类型参数的上限。
    List<String> list = new ArrayList<>();
    //类型被擦除了,保留的是类型的上限,String的上限就是Object
    List list1 = list;
    如果我把没有类型参数的集合赋值给带有类型参数的集合赋值,这又会怎么样??
    List list = new ArrayList();
    List<String> list2 = list;
    它也不会报错,仅仅是提示“未经检查的转换
    












    种一棵树最好的时间是十年前,其次是现在。
  • 相关阅读:
    项目实践精解读后感(需求分析注意点)
    XP@Scrum
    项目实践精解读后感2(需求分析注意点)
    十一过后,反思。
    可以自动化功能测试了Selenium
    部分关键字段重复的记录(保留最后记录)
    算是代码优化吗?还可以继续优化吗?
    hql查询~
    通用权限管理设计 之 数据库结构设计(摘录)
    jQuery Liger~
  • 原文地址:https://www.cnblogs.com/islch/p/12595037.html
Copyright © 2020-2023  润新知