`

自定义泛型方法及其应用和类型参数的类型推断

阅读更多

自定义泛型方法用其应用

1. 定义泛型方法

a. java的泛型方法没有C++函数功能强大,java中的如下代码无法通过编译:

<T> T add(T x, T y) {

return (T) (x + y);

}

2. 交换数组中的两个元素的位置 //下面的方法很通用,这样做还是有意义的

private static <T> void swap(T[] a,int i, int j) {

T tmp = a[i];

a[i] = a[j];

a[j] = tmp;

}

3. 用于放置泛型的类型参数的尖括号应出现在方法的其它所有修饰符之后和在方法的返回类型之前,也就是紧邻返回之前。按照惯例,类型参数通常用单个大写字母表示。

例:private static <T> void swap(T[] a,int i, int j){};

4. 除了在应用泛型时可以使用extends 限定符,在定义泛型时也可以使用extends限定符,例如,Class.getAnnotation()方法的定义。并且可以用&来指定多个边界,
<V extends Serializable & cloneable> void method(){};

5. 普通方法、构造方法和静态方法中都可以泛型。

6 也可以用类型变量表示异常,称为参数化的异常,可以用于方法的throws列表中,但是不能用于catch子句中。 //貌似有点问题,报错

private static <T extends Exception> sayHello() throws T {

try {

 

}catch (Exception e) {

thorw (T)e;

}

}

7. 在泛型中可以同时有多个类型参数,在定义它们的类括号中用逗号分开,例如:

public static <K,V> V getValue(K key) {return map.get(key);}

编写一个泛型方法,自动将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;

}

}

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

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

public static void printCollection(Collection<?> collection) {

System.out.println(collection.size());

for(Object obj: collection) {

System.out.println(obj);

}

}

 

public static <T> void printCollection2(Collection<T> collection, T obj2) {

System.out.println(collection.size());

for(Object obj: collection) {

System.out.println(obj);

}

collection.add(obj2);

}

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

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

类型参数的类型推断

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

2. 根据调用泛型方法时实际传递的参数类型或值的类型来推断,具体规则如下:
a.
当草棚个类变量只在整个参数列表中的所有和返回值中的一处被应用了,那么根据调用 方法时该处的实际应用类型来确定,这很容易凭着感觉推断来来,即直接根据调用方法时传递的参数类型或返回值来决定泛型参数的类型。例如:

swap(new String[3],3,4)->static <E> void Swap(E[] a, int i, int j);

b. 当某个类型变更在整个参数列表中所胡参数和返回值的多处被应用了,如果调用方法时这多处的实际应用类型都对就同各种类型来确定,这很容易凭感觉推断出来,例如:
add(3,5)->static <T> add(T a, T b);

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

d. 当某个类型变量在整个参数列表中的所有参数和返回值中的多处被应用了,如果调用方法时这多处的实际应用类型对应到了不同的类型,并且使用返回值,这时候优先考虑返回值的类型,例如,下面的语句实际对应的类型就是Integer了,编译器将报告错误,将变量X的类型改为float,对比Eclipse报告错误提示,接着再将变量X类型改为Number,则没有了错误:

int x = (3.35f) -> sttic <T> add(T a, T b);

 

分享到:
评论

相关推荐

    自定义泛型集合

    7. **类型推断**:从Java 7开始,我们可以使用钻石操作符`&lt;&gt;`来简化泛型类型的实例化,编译器会自动推断出类型。例如: ```java CustomList&lt;Integer&gt; list = new CustomList(); ``` 8. **效率提升**:使用泛型...

    泛型方法的使用.rar

    - **类型推断**:在调用泛型方法时,如果编译器能够确定类型参数的值,那么可以省略类型参数。例如,`Swap(1, 2)`会自动推断出`T`为`int`。 - **泛型接口和泛型类**:除了泛型方法,还可以有泛型接口(如`...

    c# 泛型应用实例

    10. **泛型与反射**:通过反射,我们可以动态地创建泛型类型实例,获取和设置泛型类型字段,调用泛型方法等。这对于构建元编程和动态代码生成的场景非常有用。 总的来说,C#泛型的应用实例非常广泛,从简单的数据...

    Java-Custom-Generics:在 Java 中使用自定义泛型的简单示例

    在自定义泛型类中,我们可以定义一个或多个类型参数,这些参数在实例化类或使用泛型方法时会被具体的类型替换。这样做可以确保对象的创建和操作都遵循我们设定的类型规则。 下面是一些关于在Java中使用自定义泛型的...

    泛型完整代码.zip

    3. **泛型方法**:我们也可以在类或接口的普通方法中使用泛型,如`public &lt;T&gt; void printArray(T[] array) {...}`,`&lt;T&gt;`定义了方法级别的类型参数。 4. **通配符**:在处理泛型时,有时我们并不关心具体的类型,只...

    C#泛型学习和理解代码示例

    我们还可以创建嵌套的泛型类型,例如`Dictionary, TValue&gt;`,其中`TKey`和`TValue`都是泛型类型参数。 10. **泛型与接口、抽象类的结合**: 泛型类型可以实现接口或继承抽象类。例如,`GenericStack&lt;T&gt;`可以实现`...

    java泛型,java知识

    - 泛型(Generics)允许在定义类、接口和方法时声明类型参数,从而创建泛型类、泛型接口和泛型方法。这使得代码可以处理多种类型的对象,而不必为每种类型都创建单独的类或方法。 - 类型参数通常以大写字母表示,...

    jdk5.zip_java 泛型_jdk5 泛型_泛型

    泛型允许程序员在类、接口和方法中使用类型参数,使得容器(如ArrayList、LinkedList等)可以保存特定类型的元素,避免了强制类型转换的麻烦,并且在编译阶段就能发现可能的类型错误。 1. **泛型的基本概念**: - ...

    学习泛型语法3

    1. **泛型类**:自定义带有类型参数的类,如`class Box&lt;T&gt; { T item; }`,其中T是类型参数,代表某种未知的类型。 2. **泛型方法**:在方法签名中使用类型参数,如`public static &lt;T&gt; void printArray(T[] array) {....

    java 泛型基础简单事例

    8. **类型推断**:Java 7 引入了类型推断,使得在创建泛型对象时可以省略类型参数,编译器会根据上下文自动推断类型。 通过理解和应用这些泛型概念,开发者可以编写出更加健壮、高效且易于维护的Java代码。在处理...

    泛型.rar

    在Java中,泛型允许我们在定义类、接口和方法时使用类型参数,而不是具体的类型,从而实现对多种类型的支持。这样做可以防止在运行时出现ClassCastException,并在编译时就捕获潜在的类型不匹配错误。 1. **泛型的...

    Java1.5泛型指南中文版

    8. **泛型方法(Generic Methods)**:除了泛型类和接口,还可以定义泛型方法,方法签名中包含类型参数。 9. **类型推断(Type Inference)**:Java 7及以后的版本支持类型推断,编译器可以根据上下文自动推断类型...

    C#语言规范2.0(C# 2.0中的重点难点)

    - **20.5.2 开放和封闭类型**:开放类型指未实例化的泛型类型,封闭类型是指已经实例化的泛型类型。 - **20.5.3 构造类型的基类和接口**:泛型类型继承自的基类和实现的接口。 - **20.5.4 构造类型的成员**:构造...

    C#2.0最新体验(1)

    3. **约束条件**:泛型类型参数可以有约束,限制它们可以是哪些类型。例如,我们可以指定类型参数必须实现某个接口或继承自特定基类,或者必须具有默认构造函数。这样,我们可以在泛型类或方法中使用这些类型的特定...

    19-Generic-Programming-in-Java.ppt

    泛型允许开发者在类、接口和方法中定义类型参数,从而创建可以操作多种数据类型的代码。在讲解泛型编程之前,我们需要先理解一些基本概念。 首先,泛型的主要目标是提供类型检查,这意味着在编译阶段就能检测到潜在...

    第十五课 泛型基础1

    在实际前端开发中,我们可以在React组件、数据处理函数、甚至自定义数据结构(如队列、堆栈等)中应用泛型。例如,创建一个泛型数组操作函数,可以处理任何类型的数组,而不局限于特定类型: ```typescript ...

    五分钟重温委托,匿名方法,Lambda,泛型委托,表达式树 - 文章 - 伯乐在线1

    泛型委托允许我们在定义委托时使用类型参数,使得委托可以适用于多种数据类型。在某些情况下,我们可能希望一个委托能够处理不同类型的数据,泛型委托就能满足这种需求。例如,我们可以定义一个泛型版本的 `...

    MSDN_C#编程指南

    - **引用类型参数**:引用类型参数按引用传递,方法中对参数的修改会影响原始对象。 #### 二十八、使用构造函数 - **构造函数类型**:介绍不同类型的构造函数,如默认构造函数、带参数构造函数等。 - **构造函数的...

    实例讲解C# 泛型(Generic)

    通过反射,可以在运行时获取关于泛型类型和实例的信息,包括类型参数及其约束。这在元数据操作和动态编程场景中非常有用。 总之,C# 泛型(Generic)是提高代码灵活性、可维护性和性能的重要特性,它允许开发者编写...

    个人学习TS的基本知识点

    TypeScript 是一种强类型的静态类型语言,它是 JavaScript 的超集,为开发者提供了更丰富的类型系统和工具支持,有助于提升代码...在实际项目中,不断实践和应用这些知识,你的 TypeScript 技术水平将会得到显著提升。

Global site tag (gtag.js) - Google Analytics