L--Java泛型、泛型类、泛型接口和泛型方法

简介

泛型出现的动机在于:为了建立容器类java

泛型类

容器类应该算得上最具重用性类库之一。先来看一下没有泛型的状况下的容器类如何定义:编程

public class Container {
    private String key;
    private String value;

    public Container(String k,String v) {
        key = k;
        value = v;
    }

    public String getKey() {
        return key;
    }

    public void setKey (String key) {
        this.key = key;
    }

    public String getValue() {
        return value;
    }

    public void setValue (String value) {
        this.value = value;
    }
}

Container类保存了一对key-value键值对,可是类型是定死的,也就说若是我想要建立一个键值对是String-Integer类型的,当前这个容器作不到的,必须再自定义。那么这明显重用性就很是低。app

 固然,能够用Object来代替String,而且在javaSE5以前,咱们也只能这么作,因为Object是全部类型的基类,因此能够直接转型。可是这样灵活性仍是不够,由于仍是指定了类型,只不过此次指定的类型层级dom

更高而已,有没有可能不指定类型?有没有可能在运行时才知道具体的类型是什么?ide

so,就出现了泛型。ui

public class Container<K,V> {
    private K key;
    private V value;

    public Container(K k,V v) {
        key = k;
        value = v;
    }

    public K getKey() {
        return key;
    }

    public void setKey (K key) {
        this.key = key;
    }

    public V getValue() {
        return value;
    }

    public void setValue (V value) {
        this.value = value;
    }
}

 

在编译期,是没法知道K和V具体是什么类型,只有在运行时才会真正根据类型来构造和分配内存。能够看一下如今Container类对于不一样类型的支持状况:this

public class Main{

    public static void main (String[] args) {
        Container<String String> c1 = new Container<String, String>("name", "gudoumaoning");
        Container<String Integer> c1 = new Container<String, Integer>("age", "24");
        Container<Double Double> c1 = new Container<Double, Integer>(1.2, 1.3);

        System.out.println(c1.getKey() + ":" + c1.getValue());
        System.out.println(c2.getKey() + ":" + c2.getValue());
        System.out.println(c3.getKey() + ":" + c3.getValue());

    } 
}
//输出:
name : gudoumaoning
age : 24
1.2 : 1.3

泛型接口

在泛型结构中,生成器是一个很好的理解,看以下的生成器接口定义:spa

public interface Generator<T> {
    public T next();
}
而后定义一个生成器类来实现这个接口:
public class FruiteGenerator implements Generator<String> {
    private String[] fruite = new String[] {"apple", "banana", "pear"};

    @Override
    public String next() {
        Random rand = new Random();
        return fruits[rand.nextInt(3)];
    }
}

 调用:code

public class Main {
    public static void main (String[] args) {
        FruiteGenerator fruitegenerator = new FruiteGenerator();

        System.out.println(fruitegenerator.next());
        System.out.println(fruitegenerator.next());
        System.out.println(fruitegenerator.next());
        System.out.println(fruitegenerator.next());
    }
}
//输出:
apple
pear
pear
banana

泛型方法

一个基本原则是:不管什么时候,只要你能作到,你就尽可能使用泛型方法。也就是说,若是泛型方法能够取代将整个类泛化,那么应该有限采用泛型方法。下面来看一个简单的泛型方法的定义:blog

public class Main {

    public static <T> void out(T t) {
        System.out.println(t);
    }

    public static void main (String[] args) {
        out("gudoumaoning");
        out(123);
        out(11.11);
        out(false);
    }
}
能够看到方法的参数完全泛化了,这个过程涉及到编译器的类型推导和自动打包,也就是说原来须要咱们本身对类型进行的判断和处理,如今编译器帮咱们作了。这样在定义方法的时候没必要考虑之后到底要处理
哪些类型的参数,大大增长了编程 的灵活性。
 
再看一个泛型和可变参数的例子:
public class Main {

    public static <T> void out(T... args) {
        for (T t: args) {
            System.out.println(t);
        }        
    }

    public static void main (String[] args) {
        out("gudoumaoning", 123, 11.11, false);
    }
}

 输出和前一段代码相同,能够看到泛型能够和可变参数完美结合。

相关文章
相关标签/搜索