Java基础进阶泛型

简介: Java基础进阶泛型

1、JDK5.0之后推出的新特性:泛型


2、泛型这种语法机制,只在程序编译阶段起作用,只是给编译器参考的。(运行阶段泛型没用!)


3、使用了泛型好处是什么?


第一:集合中存储的元素类型统一了。

第二:从集合中取出的元素类型是泛型指定的类型,不需要进行大量的“向下转型”!

4、泛型的缺点是什么?


导致集合中存储的元素缺乏多样性!

大多数业务中,集合中元素的类型还是统一的。所以这种泛型特性被大家所认可。


示例代码01:


public class GenericTest01 {
    public static void main(String[] args) {
        List myList = new ArrayList();
        // 准备对象
        Cat c = new Cat();
        Bird b = new Bird();
        // 将对象添加到集合当中
        myList.add(c);
        myList.add(b);
        // 遍历集合,取出每个Animal,让它move
        Iterator it = myList.iterator();
        while(it.hasNext()){
            // 没有这个语法,通过迭代器取出的就是Object
            //Animal a = it.next();
            Object obj = it.next();
            if(obj instanceof Animal){
                Animal a = (Animal) obj;
                a.move();
            }
        }
        //使用泛型
        // 使用JDK5之后的泛型机制
        // 使用泛型List<Animal>之后,表示List集合中只允许存储Animal类型的数据。
        // 用泛型来指定集合中存储的数据类型。
        List<Animal> l2 = new ArrayList<Animal>();
        // 指定List集合中只能存储Animal,那么存储String就编译报错了。
        // 这样用了泛型之后,集合中元素的数据类型更加统一了。
        Cat c1 = new Cat();
        Bird b1 = new Bird();
        l2.add(c1);
        l2.add(b1);
        // 获取迭代器
        // 这个表示迭代器迭代的是Animal类型。
        Iterator<Animal> it1 = l2.iterator();
        while(it1.hasNext()){
            // 使用泛型之后,每一次迭代返回的数据都是Animal类型。
            //Animal a = it.next();
            // 这里不需要进行强制类型转换了。直接调用。
            //a.move();
            // 调用子类型特有的方法还是需要向下转换的!
            Animal a1 = it1.next();
            if(a1 instanceof Bird){
                Bird b2 = (Bird) a1;
                b2.fly();
            }else if(a1 instanceof Cat){
                Cat c2 = (Cat) a1;
                c2.catchMouse();
            }
        }
    }
}
class Animal{
    public void move(){
        System.out.println("动物在移动!");
    }
}
class Cat extends Animal{
    public void catchMouse(){
        System.out.println("猫抓老鼠!");
    }
}
class Bird extends Animal{
    public void fly(){
        System.out.println("鸟儿在飞翔!");
    }
}


运行结果:


0a2653c851af460fa595bd959398a8f1.png


5、JDK之后引入了:自动类型推断机制。(又称为钻石表达式)


示例代码02:


public class GenericTest02 {
    public static void main(String[] args) {
        // ArrayList<这里的类型会自动推断>(),前提是JDK8之后才允许。
        // 自动类型推断,钻石表达式!
       List<Animal> myList = new ArrayList<>();
       myList.add(new Animal());
       myList.add(new Cat());
       myList.add(new Bird());
       Iterator<Animal> it = myList.iterator();
       while(it.hasNext()){
           Animal a = it.next();
           a.move();
       }
       List<String> l1 = new ArrayList<>();
       l1.add("http://www.126.com");
       l1.add("http://www.baidu.com");
       l1.add("http://www.newstudy.com");
        Iterator<String> it1 = l1.iterator();
        while(it1.hasNext()){
            // 如果没有使用泛型
            /*
            Object obj = it2.next();
            if(obj instanceof String){
                String ss = (String)obj;
                ss.substring(7);
            }
             */
            // 直接通过迭代器获取了String类型的数据
            String s = it1.next();
            // 直接调用String类的substring方法截取字符串。
            String sub = s.substring(7);
            System.out.println(sub);
        }
    }
}


运行结果:


2d65d23f6d4748949b924e4057485923.png


6、自定义泛型


自定义泛型可以吗?可以

自定义泛型的时候,<> 尖括号中的是一个标识符,随便写。

java源代码中经常出现的是:


E是Element单词首字母。

T是Type单词首字母。


示例代码03:


public class GenericTest03<标识符随便写> {
    public void doSome(标识符随便写 o){
    }
    public static void main(String[] args) {
        // new对象的时候指定了泛型是:String类型
        GenericTest03<String> s = new GenericTest03<>();
        s.doSome("123");
        //s.doSome(new Animal());//报错类型不匹配
        GenericTest03<Integer> i = new GenericTest03<>();
        i.doSome(123);
        //i.doSome("123");//报错类型不匹配
        MyGeneric<String> m = new MyGeneric<>();
        String s1 = m.getT();
        MyGeneric<Animal> m1 = new MyGeneric<>();
        Animal a = m1.getT();
        //不使用泛型返回的就是Object类型
        MyGeneric m3 = new MyGeneric();
        Object o = m3.getT();
    }
}
class MyGeneric<T>{
    public T getT(){
        return null;
    }
}
相关文章
|
22天前
|
存储 Java 编译器
深入理解 Java 泛型和类型擦除
【4月更文挑战第19天】Java泛型是参数化类型,增强安全性与可读性,但存在类型擦除机制。类型擦除保证与旧版本兼容,优化性能,但也导致运行时无法访问泛型信息、类型匹配问题及数组创建限制。为应对这些问题,可使用Object类、instanceof运算符,或借助Guava库的TypeToken获取运行时类型信息。
|
4天前
|
安全 Java 程序员
Java 泛型
Java 泛型
9 0
|
2天前
|
存储 安全 Java
掌握8条泛型规则,打造优雅通用的Java代码
掌握8条泛型规则,打造优雅通用的Java代码
掌握8条泛型规则,打造优雅通用的Java代码
|
9天前
|
Java
JAVA难点包括异常处理、多线程、泛型和反射,以及复杂的分布式系统知识
JAVA难点包括异常处理、多线程、泛型和反射,以及复杂的分布式系统知识。入坑JAVA因它的面向对象特性、平台无关性、强大的标准库和活跃的社区支持。
31 2
|
14天前
|
安全 Java 编译器
【JAVA】泛型和Object的区别
【JAVA】泛型和Object的区别
|
17天前
|
存储 算法 Java
滚雪球学Java(20):Java泛型与枚举:提升代码灵活性与可读性
【4月更文挑战第9天】🏆本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
27 1
滚雪球学Java(20):Java泛型与枚举:提升代码灵活性与可读性
|
17天前
|
Java
|
17天前
|
安全 Java 机器人
|
17天前
|
Java API 调度
[AIGC] 深入理解Java并发编程:从入门到进阶
[AIGC] 深入理解Java并发编程:从入门到进阶
|
17天前
|
存储 安全 Java
每日一道Java面试题:说一说Java中的泛型?
今天的每日一道Java面试题聊的是Java中的泛型,泛型在面试的时候偶尔会被提及,频率不是特别高,但在日后的开发工作中,却是是个高频词汇,因此,我们有必要去认真的学习它。
18 0