• Java 泛型-泛型类、泛型方法、泛型接口、通配符、上下限


    泛型:

            一种程序设计语言的新特性,于Java而言,在JDK 1.5开始引入。泛型就是在设计程序的时候定义一些可变部分,在具体使用的时候再给可变部分指定具体的类型。使用泛型比使用Object变量再进行强制类型转换具有更好的安全性和可读性。在Java中泛型主要体现在泛型类、泛型方法和泛型接口中。


    泛型类:

            当一个类要操作的引用数据类型不确定的时候,可以给该类定义一个形参。用到这个类的时候,通过传递类型参数的形式,来确定要操作的具体的对象类型。在JDK1.5之前,为了提高代码的通用性,通常把类型定义为所有类的父类型:Object,这样做有两大弊端:1. 在具体操作的时候要进行强制类型转换;2. 这样还是指定了类型,还是不灵活,对具体类型的方法未知且不安全。

            泛型类的格式:在类名后面声明类型变量<E>   ,泛型类可以有多个类型变量, 如:public class MyClass<K, V>


    什么时候使用泛型类?

            只要类中操作的引用数据类型不确定,就可以定义泛型类。通过使用泛型类,可以省去强制类型转换和类型转化异常的麻烦。


     泛型类例子:

            在这里定义两个类:Teacher 和 Student,定义一个泛型类Util<E>,其中getE()的作用是根据传入的对象,返回具体的对象。在main()方法中,传入具体的类型为Student和Teacher,再进一步操作。

    1. public class Generic {  
    2.   
    3.     public static void main(String[] args) {  
    4.           Util<Student> ts = new Util<Student>();  
    5.         System.out.println(ts.getE(new Student("Student","三年级" ,22)).getGrade());  
    6.         Util<Teacher> tt = new Util<Teacher>();  
    7.         System.out.println(tt.getE(new Teacher("Teacher",22)).getName());  
    8.           
    9.     }  
    10.       
    11. }  
    12. class Util<E>{  
    13.     public E getE(E e){  
    14.         return e;  
    15.     }  
    16. }  
    17.   
    18. class Teacher{  
    19.     String name;  
    20.     int age;  
    21.     public Teacher() {  
    22.     }  
    23.       
    24.     public Teacher(String name, int age){  
    25.         this.name = name;  
    26.         this.age = age;  
    27.     }  
    28.      Some  Getter & Setter functions  
    29. }  
    30. class Student{  
    31.     String name;  
    32.     String grade;  
    33.     int number;  
    34.       
    35.     public Student(String name, String grade, int number){  
    36.         this.name = name;  
    37.         this.grade = grade;  
    38.         this.number = number;  
    39.     }  
    40.     Some Getter & Setter functions  
    41.       
    42. }  

    
    

    泛型方法:

             泛型方法也是为了提高代码的重用性和程序安全性。编程原则:尽量设计泛型方法解决问题,如果设计泛型方法可以取代泛型整个类,应该采用泛型方法。

            泛型方法的格式:类型变量放在修饰符后面和返回类型前面, 如:public static <E> E getMax(T... in)

    泛型方法例子:

    1. public class GenericFunc {  
    2.   
    3.     public static void main(String[] args) {  
    4.         print("hahaha");  
    5.         print(200);  
    6.     }  
    7.       
    8.     public static <T> void print(T t){  
    9.         System.out.println(t.toString());  
    10.     }  
    11.   
    12. }  

    泛型接口:

            将泛型原理用于接口实现中,就是泛型接口。

          泛型接口的格式:泛型接口格式类似于泛型类的格式,接口中的方法的格式类似于泛型方法的格式。


    泛型接口例子:

    MyInterface.java

    1. public interface MyInteface<T> {  
    2.     public T read(T t);  
    3. }  

    Generic2.java

    1. public class Generic2 implements MyInterface<String>{  
    2.   
    3.     public static void main(String[] args) {  
    4.         Generic2 g = new Generic2();  
    5.         System.out.println(g.read("hahaha"));  
    6.     }  
    7.   
    8.     @Override  
    9.     public String read(String str) {  
    10.         return str;  
    11.     }  
    12.   
    13. }  

    泛型通配符:

            当操作的不同容器中的类型都不确定的时候,而且使用的元素都是从Object类中继承的方法,这时泛型就用通配符“?”来表示。

    泛型的通配符:“?”  相当于 “? extends Object


    泛型通配符例子:

    1. import java.util.ArrayList;  
    2. import java.util.Collection;  
    3. import java.util.HashSet;  
    4. import java.util.Iterator;  
    5.   
    6. public class AllCollectionIterator {  
    7.   
    8.     public static void main(String[] args) {  
    9.         HashSet<String> s1 = new HashSet<String>();  
    10.         s1.add("sss1");  
    11.         s1.add("sss2");  
    12.         s1.add("sss3");  
    13.           
    14.           
    15.         ArrayList<Integer> a1 = new ArrayList<Integer>();  
    16.         a1.add(1);  
    17.         a1.add(2);  
    18.         a1.add(3);  
    19.         a1.add(4);  
    20.           
    21.         printAllCollection(a1);  
    22.         System.out.println("-------------");  
    23.         printAllCollection(s1);  
    24.     }  
    25.       
    26.     public static void printAllCollection(Collection<?> c){  
    27.         Iterator<?> iter = c.iterator();  
    28.         while (iter.hasNext()) {  
    29.             System.out.println(iter.next().toString());  
    30.               
    31.         }  
    32.     }  
    33.   
    34. }  

    泛型限定:

            泛型限定就是对操作的数据类型限定在一个范围之内。限定分为上限和下限。

            上限:? extends E   接收E类型或E的子类型

            下限:? super E    接收E类型或E的父类型

            限定用法和泛型方法,泛型类用法一样,在“<>”中表达即可。

            一个类型变量或通配符可以有多个限定,多个限定用“&”分隔开,且限定中最多有一个类,可以有多个接口;如果有类限定,类限定必须放在限定列表的最前面。如:T extends MyClass1 & MyInterface1 & MyInterface2


          在Collection<E>接口中addAll()就用到泛型限定。

    addAll(Collection<? extends E> c)
              将指定 collection 中的所有元素都添加到此 collection 中(可选操作)。


    泛型限定的例子:

            这个例子的作用是计算最大值。

    1. import java.util.Calendar;  
    2. import java.util.GregorianCalendar;  
    3.   
    4. public class GenericGetMax {  
    5.   
    6.     public static void main(String[] args) {  
    7.         String[] inArrStr = {"haha""test""nba""basketball"};  
    8.         System.out.println(GetMax.findMax(inArrStr).toString());  
    9.         Integer[] inArrInt = {11332100101};  
    10.         System.out.println(GetMax.findMax(inArrInt));  
    11.         GregorianCalendar[] inArrCal = {  
    12.                 new GregorianCalendar(2016, Calendar.SEPTEMBER, 22),  
    13.                 new GregorianCalendar(2016, Calendar.OCTOBER, 10)};  
    14.         System.out.println(GetMax.findMax(inArrCal).toZonedDateTime());  
    15.     }  
    16. }  
    17.   
    18. class GetMax {  
    19.     @SafeVarargs  
    20.     public static <T extends Comparable> T findMax(T... in) {  
    21.         T max = in[0];  
    22.         for (T one : in) {  
    23.             if (one.compareTo(max) > 0) {  
    24.                 max = one;  
    25.             }  
    26.         }  
    27.   
    28.         return max;  
    29.     }  
    30. }  





  • 相关阅读:
    java多线程详解(7)-线程池的使用
    mysql学习(4)-mysqldump备份和恢复数据
    mysql学习(3)-linux下mysql主从复制
    java多线程详解(5)-Threadlocal用法
    java多线程详解(4)-多线程同步技术与lock
    java多线程详解(3)-线程的互斥与同步
    iava多线程详解(2)-成员变量与局部变量访问
    java多线程详解(1)-多线程入门
    redis 的消息发布订阅
    redis 数据类型
  • 原文地址:https://www.cnblogs.com/jpfss/p/8277088.html
Copyright © 2020-2023  润新知