泛型(一)

泛型(一)

在学习树结构中遇到了一种叫做函数对象的东西,是基于泛型来实现的,本着解决依赖的原则,回到《java编程思想》中把泛型这个章节读了一遍。所幸在章节最后有提到这个设计理念。

泛型基本用法

简单的泛型

泛型最常用的形式就是在定义一个类的时候添加一个类型变量,该变量用尖括号包起来;这个变量可以在该类中使用:1. 作为域的类型申明;2. 作为方法的返回值;3. 作为方法的参数
泛型的最主要的使用场景就是容器,当用一个类来持有特定类型的对象的时候,在使用泛型之前,我们是使用Object类型来实现这个功能,使用Object的缺点是:

  1. 这个容器不能持有特定类型的对象
  2. 取出被持有的对象时需要向上转型
package generics;
class Apple{}
class Orange{}
public class HolderUseObject{
    private Object[] items = new Object[2];
    public void put(int index, Object item){
        if(index>2)
            throw new RuntimeException();
        items[index-1] = item;
    }
    public Object get(int index){
        if(index>2)
            throw new RuntimeException();
        return items[index-1];
    }
    public HolderUseObject(){

    }
    public static void main(String[] args){
        HolderUseObject holderUseObject = new HolderUseObject();
        holderUseObject.put(1, new Apple());
        holderUseObject.put(2, new Orange()); // 放入了不是苹果的对象
        //Apple apple = holderUseObject.get(1); error: incompatible types: Object cannot be converted to Apple
        Apple apple = (Apple)holderUseObject.get(1);//需要向下转型
    }
}

而使用泛型可以避免这些问题:

package generics;
import java.lang.reflect.*;
public class HolderUseGenerics<T>{
    private T[] items;
    public void put(int index, T item){//使用类型变量作为类型参数
        if(index>2)
            throw new RuntimeException();
        items[index-1] = item;
    }
    public T get(int index){//使用类型变量作为返回值
        if(index>2)
            throw new RuntimeException();
        return items[index-1];
    }
    public HolderUseGenerics(){
        items = (T[]) new Object[2]; //泛型数组的建立 "unchecked"
    }
    public static void main(String[] args){
        HolderUseGenerics<Apple> holderUseGenerics = new HolderUseGenerics<>();//java8可以使用菱形运算符避免重复的类型变量申明
        holderUseGenerics.put(1, new Apple());
        //holderUseGenerics.put(2, new Orange());incompatible types: Orange cannot be converted to Apple 不再可以放入其他类型的对象
        Apple apple = holderUseGenerics.get(1);//不需要向下转型
    }
}

泛型接口

泛型接口的使用和泛型在类型中的使用差不多,我们在定义这个接口的时候添加一个类型参数,在使用这个接口的时候给出类型参数
接口可以: 1. 被类实现; 2. 做为变量的类型申明; 3. 方法的输入参数; 4. 方法的返回参数;

package generics;
public interface GenericsInterface<T>{
    T next();
}
class AInterfaceCat implements GenericsInterface<String>{
    public String next(){
        return "hello";
    }
    public static void main(String[] args){
        AInterfaceCat a = new AInterfaceCat();
        System.out.println(a.next());
    }
}
class BInterfaceCat{
    GenericsInterface<String> aInterface = new AInterfaceCat();//作为变量的类型申明
    public static void asInput(GenericsInterface<String> input){//方法的输入参数
    }
    public static GenericsInterface<String> asOutput(){//方法的返回参数
        return new AInterfaceCat();
    }
}

泛型方法

泛型方法是独立于类存在的,和类本身有没有类型参数没关系,当一个方法是静态的时候,他将无法访问类型变量,这个时候泛型方法显得尤为重要,书中范例:

public class GenericMethods {
  public <T> void f(T x) {//泛型方法f
    System.out.println(x.getClass().getName());//打印类全名
  }
  public static void main(String[] args) {
    GenericMethods gm = new GenericMethods();
    gm.f("");
    gm.f(1);
    gm.f(1.0);
    gm.f(1.0F);
    gm.f('c');
    gm.f(gm);
  }
}
/*输出:
java.lang.String
java.lang.Integer
java.lang.Double
java.lang.Float
java.lang.Character
GenericMethods
*/

类型参数推断

当使用泛型方法执行赋值操作的时候,可以不添加对应的类型参数,直接使用方法名,编译器会对类型参数自动推断

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值