泛型类

泛型类

泛型类就是把泛型定义在类上,用户使用该类的时候,才把类型明确下来。这样的话,用户明确了什么类型,该类就代表着什么类型。用户在使用的时候就不用担心强转的问题,运行时转换异常的问题了。

/* 把泛型定义在类上,类型变量定义在类上,方法中也可以使用 */
public class ObjectTool<T> {
    private T obj;

    public T getObj() {
        return obj;
    }

    public void setObj(T obj) {
        this.obj = obj;
    }
}

public static void main(String[] args) {
    // 创建对象并指定元素类型
    ObjectTool<String> tool = new ObjectTool<>();

    tool.setObj(new String("钟福成"));
    String s = tool.getObj();
    System.out.println(s);


    //创建对象并指定元素类型
    ObjectTool<Integer> objectTool = new ObjectTool<>();
    /**
      * 如果我在这个对象里传入的是String类型的,它在编译时期就通过不了了.
      */
    objectTool.setObj(10);
    int i = objectTool.getObj();
    System.out.println(i);
}

泛型方法

仅仅在某一个方法上需要使用泛型,外界仅仅是关心该方法,不关心类其他的属性。

// 定义泛型方法..
public <T> void show(T t) {
    System.out.println(t);
}

public static void main(String[] args) {
    //创建对象
    ObjectTool tool = new ObjectTool();

    //调用方法,传入的参数是什么类型,返回值就是什么类型
    tool.show("hello");
    tool.show(12);
    tool.show(12.5);
}

定义泛型的浅拷贝函数:

/** 浅拷贝函数 */
public static <T> T shallowCopy(Object source, Class<T> clazz) throws BeansException {
    // 判断源对象
    if (Objects.isNull(source)) {
        return null;
    }

    // 新建目标对象
    T target;
    try {
        target = clazz.newInstance();
    } catch (Exception e) {
        throw new BeansException("新建类实例异常", e);
    }

    // 拷贝对象属性
    BeanUtils.copyProperties(source, target);

    // 返回目标对象
    return target;
}

泛型类派生出的子类

泛型类是拥有泛型这个特性的类,它本质上还是一个 Java 类,那么它就可以被继承。泛型类的继承分为两种情况:

  • 子类明确泛型类的类型参数变量
  • 子类不明确泛型类的类型参数变量

子类明确泛型类的类型参数变量

/*
    把泛型定义在接口上
 */
public interface Inter<T> {
  public abstract void show(T t);
}

/**
 * 子类明确泛型类的类型参数变量:
 */
public class InterImpl implements Inter<String> {

  @Override
  public void show(String s) {
    System.out.println(s);
  }
}

子类不明确泛型类的类型参数变量

当子类不明确泛型类的类型参数变量时,外界使用子类的时候,也需要传递类型参数变量进来,在实现类上需要定义出类型参数变量。

/**
 * 子类不明确泛型类的类型参数变量: 实现类也要定义出<T>类型的
 */
public class InterImpl<T> implements Inter<T> {
    @Override
    public void show(T t) {
        System.out.println(t);
    }
}

public static void main(String[] args) {
    //测试第一种情况
    //Inter<String> i = new InterImpl();
    //i.show("hello");

    //第二种情况测试
    Inter<String> ii = new InterImpl<>();
    ii.show("100");
}

值得注意的是,类上声明的泛型只对非静态成员有效,并且实现类的要是重写父类的方法,返回值的类型是要和父类一样的。

泛型擦除

泛型是提供给 javac 编译器使用的,它用于限定集合的输入类型,让编译器在源代码级别上,即挡住向集合中插入非法数据。但编译器编译完带有泛形的 Java 程序后,生成的 class 文件中将不再带有泛形信息,以此使程序运行效率不受到影响,这个过程称之为“擦除”。

上一页
下一页