• 博客园logo
  • 会员
  • 周边
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
风吹花落泪如雨
博客园    首页    新随笔    联系   管理    订阅  订阅

JAVA泛型(三)泛型方法

定义泛型方法

泛型形参声明放在方法修饰符和方法返回值类型之间

修饰符 <T, S> 返回值类型 方法名(形参列表){ //方法体 ...}

将一个数组的所有元素添加到一个Collection集合中:

import java.util.*;
public class a{
  static <T> void fromArrayToCollection(T[] a, Collection<T> c){
    for(T o: a){
      c.add(o);
    }
  }
  public static void main(String[] args){
    //下面T代表Object类型
    Object[] oa = new Object[100];
    Collection<Object> co = new ArrayList<>();
    fromArrayToCollection(oa,co);
    //下面T代表String类型
    String[] sa = new String[100];
    Collection<String> cs = new ArrayList<>();
    fromArrayToCollection(sa,cs);
    //下面T代表Object类型
    fromArrayToCollection(sa,co);

    Integer[] ia = new Integer[100];
    Float[] fa = new Float[100];
    Number[] na = new Number[100];
    Collection<Number> cn = new ArrayList<>(); 
    //下面T代表Number类型
    fromArrayToCollection(ia,cn);
    //下面T代表Number类型
    fromArrayToCollection(fa,cn);
    //下面T代表Number类型
    fromArrayToCollection(na,cn);
    //下面T代表Object类型
    fromArrayToCollection(na,co);
    //下面代码中T代表String类型,但na是一个Number数组
    //因为Number既不是String类型,也不是他的子类,编译错误
    //fromArrayToCollection(na,cs);
  }
}

下面代码系统会迷惑:

//若传入两个实参的类型不同,编译器无法正确识别T所代表的实际类型
static <T> void test(Collection<T> from, Collection<T> to){}

泛型方法和类型通配符的区别:

对于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产生的唯一效果是可以在不同的调用点传入不同的实际类型,对于这种情况,应该使用类型通配符:通配符就是被设计用来支持灵活的子类化的。

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

Java7的"菱形"方法和泛型构造器

class MyClass<E>{
  public <T> MyClass(T t){
    System.out.println("t参数的值为:" + t);
  }
}
public class a{
  public static void main(String[] args){
    //隐式指定
    MyClass<String> mc1 = new MyClss<>(5);
    //显示指定
    MyClass<String> mc2 = new <Integer> MyClss<String>(5);
    //此处不能使用"菱形"语法,代码错误
    MyClass<String> mc2 = new <Integer> MyClss<>(5);
  }
}

 

 Java8改进的类型推断

class MyClass<E>{
  public static <Z> MyClass<Z> nil(){
    return null;
  }
  public static <Z> MyClass<Z> cons(Z head,MyClass<Z> tail){
    return null;
  }
  E head(){
    return null;
  }
}
public class a{
  public static void main(String[] args){
    MyClass<String> ls2 = MyClass.<String>nil();
    //可简化为
    MyClass<String> ls = MyClass.nil();

    MyClass.cons(42,MyClass.<Integer>nill());
    //可简化为
    MyClass.cons(42,MyClass.nill());

  }
}

 

posted @ 2018-06-15 22:06  风吹花落泪如雨  阅读(300)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2026
浙公网安备 33010602011771号 浙ICP备2021040463号-3