天天看点

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,再进一步操作。

<b>[java]</b> view plain copy

print?

public class Generic {  

    public static void main(String[] args) {  

          Util&lt;Student&gt; ts = new Util&lt;Student&gt;();  

        System.out.println(ts.getE(new Student("Student","三年级" ,22)).getGrade());  

        Util&lt;Teacher&gt; tt = new Util&lt;Teacher&gt;();  

        System.out.println(tt.getE(new Teacher("Teacher",22)).getName());  

    }  

}  

class Util&lt;E&gt;{  

    public E getE(E e){  

        return e;  

class Teacher{  

    String name;  

    int age;  

    public Teacher() {  

    public Teacher(String name, int age){  

        this.name = name;  

        this.age = age;  

     Some  Getter &amp; Setter functions  

class Student{  

    String grade;  

    int number;  

    public Student(String name, String grade, int number){  

        this.grade = grade;  

        this.number = number;  

    Some Getter &amp; Setter functions  

        System.out.println(ts.getE(new Student("Student","三年级" ,22)).getGrade());

        Util&lt;Teacher&gt; tt = new Util&lt;Teacher&gt;();

        System.out.println(tt.getE(new Teacher("Teacher",22)).getName());

}

class Util&lt;E&gt;{

public E getE(E e){

return e;

class Teacher{

String name;

int age;

public Teacher() {

class Student{

    String name;

    String grade;

    int number;

    public Student(String name, String grade, int number){

        this.name = name;

        this.grade = grade;

        this.number = number;

    }

    Some Getter &amp; Setter functions

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

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

public class GenericFunc {  

        print("hahaha");  

        print(200);  

    public static &lt;T&gt; void print(T t){  

        System.out.println(t.toString());  

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

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

MyInterface.java

public interface MyInteface&lt;T&gt; {  

    public T read(T t);  

Generic2.java

public class Generic2 implements MyInterface&lt;String&gt;{  

        Generic2 g = new Generic2();  

        System.out.println(g.read("hahaha"));  

    @Override  

    public String read(String str) {  

        return str;  

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

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

import java.util.ArrayList;  

import java.util.Collection;  

import java.util.HashSet;  

import java.util.Iterator;  

public class AllCollectionIterator {  

        HashSet&lt;String&gt; s1 = new HashSet&lt;String&gt;();  

        s1.add("sss1");  

        s1.add("sss2");  

        s1.add("sss3");  

        ArrayList&lt;Integer&gt; a1 = new ArrayList&lt;Integer&gt;();  

        a1.add(1);  

        a1.add(2);  

        a1.add(3);  

        a1.add(4);  

        printAllCollection(a1);  

        System.out.println("-------------");  

        printAllCollection(s1);  

    public static void printAllCollection(Collection&lt;?&gt; c){  

        Iterator&lt;?&gt; iter = c.iterator();  

        while (iter.hasNext()) {  

            System.out.println(iter.next().toString());  

        }  

public class AllCollectionIterator {

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

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

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

        限定用法和泛型方法,泛型类用法一样,在“&lt;&gt;”中表达即可。

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

      在Collection&lt;E&gt;接口中addAll()就用到泛型限定。

<code>addAll(Collection&lt;? extends E&gt; c)</code>

          将指定 collection 中的所有元素都添加到此 collection 中(可选操作)。

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

import java.util.Calendar;  

import java.util.GregorianCalendar;  

public class GenericGetMax {  

        String[] inArrStr = {"haha", "test", "nba", "basketball"};  

        System.out.println(GetMax.findMax(inArrStr).toString());  

        Integer[] inArrInt = {11, 33, 2, 100, 101};  

        System.out.println(GetMax.findMax(inArrInt));  

        GregorianCalendar[] inArrCal = {  

                new GregorianCalendar(2016, Calendar.SEPTEMBER, 22),  

                new GregorianCalendar(2016, Calendar.OCTOBER, 10)};  

        System.out.println(GetMax.findMax(inArrCal).toZonedDateTime());  

class GetMax {  

    @SafeVarargs  

    public static &lt;T extends Comparable&gt; T findMax(T... in) {  

        T max = in[0];  

        for (T one : in) {  

            if (one.compareTo(max) &gt; 0) {  

                max = one;  

            }  

        return max;  

public class GenericGetMax {

class GetMax {

@SafeVarargs

public static &lt;T extends Comparable&gt; T findMax(T... in) {

T max = in[0];

for (T one : in) {

if (one.compareTo(max) &gt; 0) {

max = one;