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;
    }
}
相关文章
|
1月前
|
存储 缓存 Java
java基础:IO流 理论与代码示例(详解、idea设置统一utf-8编码问题)
这篇文章详细介绍了Java中的IO流,包括字符与字节的概念、编码格式、File类的使用、IO流的分类和原理,以及通过代码示例展示了各种流的应用,如节点流、处理流、缓存流、转换流、对象流和随机访问文件流。同时,还探讨了IDEA中设置项目编码格式的方法,以及如何处理序列化和反序列化问题。
67 1
java基础:IO流 理论与代码示例(详解、idea设置统一utf-8编码问题)
|
26天前
|
Java API
[Java]泛型
本文详细介绍了Java泛型的相关概念和使用方法,包括类型判断、继承泛型类或实现泛型接口、泛型通配符、泛型方法、泛型上下边界、静态方法中使用泛型等内容。作者通过多个示例和测试代码,深入浅出地解释了泛型的原理和应用场景,帮助读者更好地理解和掌握Java泛型的使用技巧。文章还探讨了一些常见的疑惑和误区,如泛型擦除和基本数据类型数组的使用限制。最后,作者强调了泛型在实际开发中的重要性和应用价值。
22 0
[Java]泛型
|
1月前
|
存储 安全 Java
🌱Java零基础 - 泛型详解
【10月更文挑战第7天】本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
11 1
|
1月前
|
Java 语音技术 容器
java数据结构泛型
java数据结构泛型
27 5
|
1月前
|
存储 Java 编译器
Java集合定义其泛型
Java集合定义其泛型
19 1
|
2月前
|
Java 编译器 容器
Java——包装类和泛型
包装类是Java中一种特殊类,用于将基本数据类型(如 `int`、`double`、`char` 等)封装成对象。这样做可以利用对象的特性和方法。Java 提供了八种基本数据类型的包装类:`Integer` (`int`)、`Double` (`double`)、`Byte` (`byte`)、`Short` (`short`)、`Long` (`long`)、`Float` (`float`)、`Character` (`char`) 和 `Boolean` (`boolean`)。包装类可以通过 `valueOf()` 方法或自动装箱/拆箱机制创建。
37 9
Java——包装类和泛型
|
1月前
|
存储 Java 编译器
【用Java学习数据结构系列】初识泛型
【用Java学习数据结构系列】初识泛型
20 2
|
2月前
|
安全 Java API
【Java面试题汇总】Java基础篇——String+集合+泛型+IO+异常+反射(2023版)
String常量池、String、StringBuffer、Stringbuilder有什么区别、List与Set的区别、ArrayList和LinkedList的区别、HashMap底层原理、ConcurrentHashMap、HashMap和Hashtable的区别、泛型擦除、ABA问题、IO多路复用、BIO、NIO、O、异常处理机制、反射
【Java面试题汇总】Java基础篇——String+集合+泛型+IO+异常+反射(2023版)
|
1月前
|
安全 Java 编译器
Java基础-泛型机制
Java基础-泛型机制
16 0
|
2月前
|
存储 安全 搜索推荐
Java中的泛型
【9月更文挑战第15天】在 Java 中,泛型是一种编译时类型检查机制,通过使用类型参数提升代码的安全性和重用性。其主要作用包括类型安全,避免运行时类型转换错误,以及代码重用,允许编写通用逻辑。泛型通过尖括号 `&lt;&gt;` 定义类型参数,并支持上界和下界限定,以及无界和有界通配符。使用泛型需注意类型擦除、无法创建泛型数组及基本数据类型的限制。泛型显著提高了代码的安全性和灵活性。
下一篇
无影云桌面