41_自定义泛型方法的练习与类型推断总结

  • 编写一个泛型方法,自动将Object类型的对象转换成其他类型。

//编写一个泛型方法,自动将Object类型的对象转换成其他类型。 
   

private static <T> T autoConvert(Object obj){
        return (T)obj;
    }

  • 定义一个方法,可以将任意类型的数组中的所有元素填充为相应类型的某个对象。
//定义一个方法,可以将任意类型的数组中的所有元素填充内容为相应类型的某个对象
    private static <T> void fillArray(T[] a,T obj){
        for(int i=0;i<a.length;i++){
            a[i]=obj;
        }
    }

  • 采用自定义泛型方法的方式打印出任意参数化类型的集合中的所有内容。

    • 在这种情况下,前面的通配符方案要比泛型方法更有效,当一个类型变量用来表达两个参数之间或者参数和返回值之间的关系时,即同一个类型变量在方法签名的两处被使用,或者类型变量在方法体代码中也被使用而不是在签名的时候使用,才需要使用泛型方法。

 

private static void printObject1(Collection<?> collection){
    System.out.println(collection.size()); 

    for(Object o:collection){
        System.out.println(o);
    } 

}

 

//采用自定义泛型方法的方式打印出任意参数化类型的集合中的所有内容。
private static <T> void printObject2(Collection<T> collection,T obj){
    for(Object o:collection){
        System.out.println(o);
    }
    collection.add(obj);//T的方式可以向集合中进行添加
}

 

  • 定义一个方法,把任意参数类型的集合中的数据安全地复制到相应的数组中。
//定义一个方法,把任意参数类型的集合中的数据安全地复制到相应的数组中
private static <T> void copy1(Collection<T> dest,T[] src){
    for(int i=0;i<src.length;i++){
        dest.add(src[i]);
    }
}

copy1(new Vector<String>(),new String[]{});

copy1(new Vector<Date>(),new String[]{});//出错!传播:Vector进行参数化时,指定了T就是Date,那么后面的另一个参数T 就必须是Date[]
  • 定义一个方法,把任意参数类型的一个数组中的数据安全地复制到相应类型的另一个数组中。

//定义一个方法,把任意参数类型的一个数组中的数据安全地复制到相应类型的另一个数组中。

private static <T> void copy2(T[] dest,T[] src){ 

}

 

 

 

 

  • 编译器判断泛型方法的实际类型参数的过程称为类型推断,类型推断是相对于知觉推断的,其实现方法是一种非常复杂的过程

 

  • 根据调用泛型方法时实际传递的参数类型或者返回值类型来推断,具体规则如下:

    • 当某个类型变量只在整个参数列表中的所有参数和返回值中的一处被应用了,那么根据调用方法时该处的实际应用类型来确定,这很容易凭着感觉推断出来,即直接根据调用方法时传递的参数类型或返回值来决定泛型参数的类型,例如:
swap(new String[3],3,4)—>static <E> void swap(E[] a,int i,int j)

    • 当某个类型变量在整个参数列表中的所有参数和返回值中的多处被应用了,如果调用方法时这多处的实际应用类型来确定,这很容易凭着感觉推断出来,例如:
add()—>static <T>T add(T a,T b)

    • 当某个类型变量在整个参数列表中的所有参数和返回值中的多处被应用了,如果调用方法时这多处的实际应用类型对应到了不同的类型,且没有使用返回值,这时候取多个参数中的最大交集类型,例如,下面的语句实际对应的类型就是Number了,编译没问题,只是运行时出问题:
fill(new Integer[3],3.5f)—>static <T> void fill(T[] a,T v)

    • 当某个类型变量在整个参数列表中的所有参数和返回值中的多处被应用了,如果调用方法时这多处的实际引用类型对应到了不同的类型,并且使用返回值,这时候优先考虑返回值的类型,例如下面的语句实际对应的类型就是Integer了,编译器将报告错误,将变量x的类型改为float,对比eclipse报告的错误提示,接着再将x类型改为Number,则没有了错误:
int x=add(3,3.5f)—>static <T> T add(T a,T b)

    • 参数类型的类型推断具有传递性,下面第一种情况推断实际参数为Object,编译没有问题,而第二种情况则根据参数化的Vector类实例将类型变量直接确定为String类型,编译将出现问题:
copy(new Integer[5],new String[5])—>static <T> void copy(T[] a,T[] b);

时间: 2024-11-07 23:45:03

41_自定义泛型方法的练习与类型推断总结的相关文章

泛型方法与类型推断

一.好处 1.代替整个类泛型化 2.static方法无法访问泛型类的类型参数,所以static方法需要使用泛型能力,就必须使其成为泛型方法. 二.示例 只需将泛型参数列表置于返回值之前. public class GenericMethods { public void f(T x) { System.out.println(x.getClass().getName()); } public static void main(String[] args) { GenericMethods gm

泛型中的类型约束和类型推断

前一篇文章介绍了泛型的基本概念.在本文中,我们看一下泛型中两个很重要的特性:类型约束和类型推断. 类型约束 相信你还记得前面一篇文章中的泛型方法,在这个泛型方法中,我们就使用了类型约束. 类型约束(type constraint)进一步控制了可指定的类型实参,当我们创建自己的泛型类型或者泛型方法的时候,类型约束是很有用的. 回到前一篇例子中的泛型方法,这个泛型方法就要求可指定的类型实参必须实现了IComparable接口. 为什么会有这个约束呢?原因很简单,因为我们在泛型方法的实现中直接调用T类

类型参数的类型推断

类型参数的类型推断(花了张老师两天的时间总结) l 编译器判断范型方法的实际类型参数的过程称为类型推断,类型推断是相对于知觉推断的,其实现方法是一种非常复杂的过程. l 根据调用泛型方法时实际传递的参数类型或返回值的类型来推断,具体规则如下: 1.当某个类型变量只在整个参数列表中的所有参数和返回值中的一处被应用了,那么根据调用方法时该处的实际应用类型来确定,这很容易凭着感觉推断出来,即直接根据调用方法时传递的参数类型或返回值来决定泛型参数的类型,例如: swap(new String[3],3,

6.6 类型推断

我们曾经讨论过值的类型推断,知道在 C# 3.0 中用 var 关键字,在 F#中用 let 绑定.从本节开始,我们将讨论由 C# 和 F# 共有的另一个方面,当在 C# 中调用泛型方法时,如 Option.Some(清单 5.9)或 Option.Map(清单 6.13),可以显式指定类型参数值,像这样: var dt = Option.Some<DateTime>(DateTime.Now); var nt = dt.Map<DateTime, int>(d=> d.Ye

类型安全和类型推断

Swift 是一个类型安全(type safe)的语言.类型安全的语言可以让你清楚地知道代码要处理的值的类型.如果你的代码需要一个String,你绝对不可能不小心传进去一个Int. 由于 Swift 是类型安全的,所以它会在编译你的代码时进行类型检查(type checks),并把不匹配的类型标记为错误.这可以让你在开发的时候尽早发现并修复错误. 当你要处理不同类型的值时,类型检查可以帮你避免错误.然而,这并不是说你每次声明常量和变量的时候都需要显式指定类型.如果你没有显式指定类型,Swift

Spring BeanFactory 中的类型推断

Spring BeanFactory 中的类型推断 Spring 系列目录(https://www.cnblogs.com/binarylei/p/10117436.html) Spring 容器中可以根据 beanName 查找其类型,其推断方式和 bean 的创建方式密切相关,并且 Spring 中有一个原则是尽可能的不要通过创建 bean 来获取其类型,除了 FactoryBean 只有通过创建对象调用其 getObjectType 方法,但也只是部分的创建该 FactoryBean(所谓

scala学习手记17 - 容器和类型推断

关于scala的类型推断前面已经提到过多次.再来看一下下面这个例子: import java.util._ var list1: List[Int] = new ArrayList[Int] var list2 = new ArrayList[Int] list2 add 1 list2 add 2 var total = 0 for (index <- 0 until list2.size()) { total += list2.get(index) } println("Total i

scala学习手记20 - 方法返回类型推断

除了推演变量的类型,scala也会推演方法的返回类型.不过这里有一处需要注意:方法返回类型的推演依赖于方法的定义方式.如果用等号"="定义方法,scala就会推演方法返回类型:否则,它就认为方法的返回为void.看一个例子: def printMethodInfo(methodName: String) { println("The return type of " + methodName + " is " + getClass().getDe

[原创]Scala学习:关于变量(val,var,类型推断)

1.常量定义:  val val 类似于java中的final变量.一旦初始化了,val就不能再被赋值 val megs = "hello world" 2.变量的定义: var var 如同java里面的非final变量,可以在它的声明周期内多次被赋值 var spark:String = " i am big data " var spark: String = " i am" 解释器中支持table键 补充和提示 3.变量类型推断: 当分配