美文网首页
泛型琐碎之泛型方法

泛型琐碎之泛型方法

作者: Twinkle_______ | 来源:发表于2016-01-31 17:16 被阅读154次

泛型

泛型:是一种把类型明确的工作推迟到创建对象或者调用方法的时候才去明确的特殊的类型。把类型当作参数传递。

格式:<数据类型> 此处的数据类型只能是引用类型, 如<E>, 丢进去的类型必须是E的对象或其子类的对象。

好处:
A:把运行时期的问题提前到了编译期间
B:避免了强制类型转换
C:优化了程序设计,解决了黄色警告线

泛型方法

such as, ResponseEntity类带有一个E类型形参

public class ResponseEntity<E> {
    private String msg;
    private String code; 
    private E data;
    
    public ResponseEntity(String code, String msg, E data) {
        this.code = code;
        this.msg = msg;
        this.data = data;
    }
    
    /*
    方法静态时,不能访问类定义上的泛型
    */
    public static <E> ResponseEntity<E> success(String code, String msg, E data) {
    // 传入什么类型,E就是什么类型 
        return new ResponseEntity<E>(code, msg, data);
    }
} 

现在假设有一个

Apple a = new Apple();
// 调用success()方法, 
ResponseEntity.success("200", "ok", a);
//这样success()方法的返回值类型 ResponseEntity<E>中的E代表Apple类型。

再比如:

public static <T> void fromArrayToCollection(T[] a, Collection<T> c) {
    for (T o : a) {
        c.add(o);
    }
}

这是一个泛型方法,该泛型方法定义一个T类型形参,这样方法就能接受任意类型的参数了。

Integer[] ia = new Integer[100];
Collection<Number>  cn = new ArrayList<>();
// T代表Number类型
// 只比较泛型形参: Collection<T> cn
fromArrayToCollection(ia, cn);

cn是Collection<Number>类型,与此方法的方法签名进行比较——只比较泛型参数,故该T类型形参代表了Number类型。

public static <T> void test(Collection<? extends T> from, Collection<T> to) {
    for (T ele : from) {
        to.add(ele);
    }
}

//String Object
List<Object> ao = new ArrayList<>();
List<String> as = new ArrayList<>();
// T代表Object类型, as中的String是Object的子类类型
test(as, ao);

泛型方法和类型通配符(?)

大多时候,可以使用泛型方法来代替类型通配符。如Java的Collection接口中的两个方法:

// 泛型通配符
public interface Collection<E> {
    boolean containsAll(Collection<?> c);
    boolean addAll(Collection<? extends E> c);
}

//采用泛型方法的形式
public interface Collection<E> {
    <T> boolean containsAll(Collection<T> c);
    <T extends E> boolean addAll(Collection<T> c);
}

上面两个方法中类型形参T只使用了一次,类型形参T产生的唯一效果是可以在不同的调用点传入不同的实际类型。对于这种情况,应该使用通配符:通配符就是被设计用来支持灵活的子类化的

泛型方法允许类型形参被用来表示方法的一个或多个参数之间的类型依赖关系,或者方法返回值与参数之间的类型依赖关系。如果没有这种依赖关系,就不应该使用泛型方法。

再来看一个栗子, Collections.copy()方法:

public class Collections {
    public static <T> void copy(List<T> dest, List<? extends T> src){...}
}
/*
src中 ? 代表的类型须是dest中 T 的子类或它本身
dest于src的类型存在明显的依赖关系
但JDK定义src时使用的是类型通配符,而不是泛型方法
Reason: 该方法无须向src集合中添加元素,也无须修改src集合里的元素,使用类型通配符,无须使用泛型方法
*/

如果改成泛型方法,不使用类型通配符:

class Collections {
    public static <T, S extends T> void copy(List<T> dest, 
    List<S> src) {...}
}
/*
这里的类型形参S, 它使用了一次, 其他参数的类型、方法返回值的类型都不依赖于它,
那类型形参S就没有存在的必要,即可以用通配符来代替S。so Java 设计该方法时采用了通配符,而不是泛型方法。
*/

类型通配符既可以在方法签名中定义形参的类型,也可以用于定义变量的类型;但泛型方法中的类型形参必须在对应方法中显式声明。

相关文章

  • 泛型琐碎之泛型方法

    泛型 泛型:是一种把类型明确的工作推迟到创建对象或者调用方法的时候才去明确的特殊的类型。把类型当作参数传递。 格式...

  • Java 泛型

    泛型类 例如 泛型接口 例如 泛型通配符 泛型方法 类中的泛型方法 泛型方法与可变参数 静态方法与泛型 泛型上下边...

  • 泛型的使用

    泛型有三种使用方式,分别为:泛型类、泛型接口、泛型方法 泛型类 泛型接口 泛型通配符 泛型方法 静态方法与...

  • 泛型 & 注解 & Log4J日志组件

    掌握的知识 : 基本用法、泛型擦除、泛型类/泛型方法/泛型接口、泛型关键字、反射泛型(案例) 泛型 概述 : 泛型...

  • 重走安卓进阶路——泛型

    ps.原来的标题 为什么我们需要泛型? 泛型类、泛型接口和泛型方法(泛型类和泛型接口的定义与泛型方法辨析); 如何...

  • Java泛型

    泛型有三种实现方式,分别是泛型接口、泛型类、泛型方法。下面通过泛型方法来介绍什么是类型参数。 泛型方法声明方式:访...

  • 【泛型】通配符与嵌套

    上一篇 【泛型】泛型的作用与定义 1 泛型分类 泛型可以分成泛型类、泛型方法和泛型接口 1.1 泛型类 一个泛型类...

  • 泛型

    一、泛型类、泛型接口和泛型方法1、泛型接口的定义: 2、两种泛型类的定义:(1) (2) 3、泛型方法的定义,可以...

  • 泛型

    关于泛型类,泛型方法,泛型接口泛型类:public class FanXingLeiDemo {//这里是泛...

  • 探秘 Java 中的泛型(Generic)

    本文包括:JDK5之前集合对象使用问题泛型的出现泛型应用泛型典型应用自定义泛型——泛型方法自定义泛型——泛型类泛型...

网友评论

      本文标题:泛型琐碎之泛型方法

      本文链接:https://www.haomeiwen.com/subject/rekskttx.html