Java泛型

Java中的泛型方法是一种特殊的方法,它可以在方法的声明中使用泛型类型参数。这样一来,我们就可以编写可以适用于多种类型的方法,并且在编译时进行类型检查。
泛型使编译器可以在编译期间对类型进行检查以提高类型安全,减少运行时由于对象类型不匹配引发的异常。

【 ?、T 、K 、V、 E 解释】

看java源代码,如果碰到了泛型,像 ?、T 、K 、V、 E 这些是经常出现的。
E    ---  Element (在集合中使用,因为集合中存放的是元素)
T    ---  Type(表示 Java 类型)
K V  ---  分别代表 java 键值中的 Key Value。
N    ---  Number(数值类型)
?    ---  表示 不确定的 Java类型
Object:Object是Java中所有类的基类,它代表任意类型。在类型擦除时,如果泛型类型参数没有限定类型,那么类型
参数会被替换为Object类型。

例如,以下是使用泛型的一些示例:
List<T>:一个泛型列表,其中T表示列表中元素的类型。
Map<K, V>:一个泛型映射,其中K表示键的类型,V表示值的类型。
Pair<T, U>:一个泛型对,其中T表示第一个元素的类型,U表示第二个元素的类型。

在MyBatis的SQLSession中对象中有很多方法比如:

1.<T> T selectOne(省略参数);
T表示 任意类型对象  如: user selectOne()       book selectOne()

2.<E> List<E> selectList(省略参数);
E  一般表示集合类型当中元素的类型 如:
List<User> selectList()         List<Book > selectList()

3.<K,V> Map<K,V> selectMap(省略参数);
泛型采用统一结构,可以将多种数据类型的元素进行一致操作。
<K,V>一般表示Map类泛型,K表示Key(键),V表示Value(值);

【泛型方法和泛型类代码示例】

(要声明一个泛型方法,需要在方法的返回类型之前加上尖括号,并在括号中指定一个或多个类型参数,此时才可以在方法中使用泛
型类型。例如:声明了<T> ,方法的返回类型或者请求参数才可以用T。)

方法使用泛型前,必须对泛型进行声明,语法:<T> ,T可以是任意字母,但通常必须要大写。
一般情况下大写是类型,小写是参数。<T>需放在方法的返回值声明之前。

泛型方法的定义格式如下:
public <T> returnType methodName(T parameter) {
    // 方法体
}
其中,`<T>`是类型参数的声明,可以是任意标识符,通常使用大写字母表示,用于表示一个未知的类型。
`returnType`是方法的返回类型,`methodName`是方法的名称,`T parameter`是方法的参数,其中 `T` 是类型参数的具体使用。
在泛型方法中,可以使用类型参数 `T` 来声明参数、返回值或在方法体中进行操作。

【代码】

public class Demo2 {
 
    //无返回值
	public <T>  void m1(T t){
		
	}
 
    //有返回值的实例方法
	public <T> T m2(T t){
		return t;
	}
 
    //有返回值的静态方法
	public static <T> T m3(T t){
		return t;
	}


/** * 泛型方法的基本介绍 
* @param tClass 传入的泛型实参 
* @return T 返回值为T类型 
* 说明:
*     1)public 与 返回值中间<T>非常重要,可以理解为声明此方法为泛型方法。 
*     2)只有声明了<T>的方法才是泛型方法,泛型类中的使用了泛型的成员方法并不是泛型方法。
*     3)<T>表明该方法将使用泛型类型T,此时才可以在方法中使用泛型类型T。
*     4)与泛型类的定义一样,此处T可以随便写为任意标识,常见的如T、E、K、V等形式的参数常用于表示泛型。 
*/
public <T> T genericMethod(Class<T> tClass)throws InstantiationException ,  IllegalAccessException
{        T instance = tClass.newInstance();     
         return instance;
}

public <T> void printArray(T[] array) {
    for (T element : array) {
        System.out.println(element);
    }
}

public <T> T getMax(T[] array) {
    T max = array[0];
    for (T element : array) {
        if (element.compareTo(max) > 0) {
            max = element;
        }
    }
    return max;
}
}


【泛型方法 `<K, V>` 的代码示例】

泛型方法 `<K, V>` 的使用方式是在方法声明中使用类型参数 `<K, V>`,使得方法可以接受不同类型的键和值,并进行相应的操作。

下面是一个示例,展示了如何使用带有类型参数 `<K, V>` 的泛型方法:


public <K, V> void printMap(Map<K, V> map) {
    for (Map.Entry<K, V> entry : map.entrySet()) {
        System.out.println("Key: " + entry.getKey() + ", Value: " + entry.getValue());
    }
}

在上述示例中,`printMap` 方法接受一个 `Map` 对象作为参数,并通过使用类型参数 `<K, V>`,可以处理任意类型的键和值。在方法体内部,通过遍历 `Map` 的键值对,并打印出对应的键和值。

调用该泛型方法时,需要传入对应的具体类型的 `Map` 对象。例如:


Map<String, Integer> intMap = new HashMap<>();
intMap.put("One", 1);
intMap.put("Two", 2);
intMap.put("Three", 3);

printMap(intMap);


上述代码创建了一个 `Map` 对象,其中键的类型为 `String`,值的类型为 `Integer`。然后调用 `printMap` 方法将该 `Map` 对象传入,输出结果如下:


Key: One, Value: 1
Key: Two, Value: 2
Key: Three, Value: 3


通过使用 `<K, V>` 类型参数,泛型方法可以处理不同类型的键和值,提高了代码的灵活性和重用性。

除了在方法上声明泛型之外,还可以在类上声明泛型
但是需要注意的是:在类上面声明泛型,仅限于实例方法上直接使用,但是不适合静态方法,静态方法上的泛型还是需要在方法上单独定义的

//在类上面声明泛型,在实例方法上直接用即可;但是不适合静态方法
//静态方法上使用的泛型声明必须单独定义
public class Demo2<T> {
 
	public void m1(T t){
		
	}
 
	public T m2(T t){
		return t;
	}
}

【 < T >和<?>和object区别?】

< T >、<?>和object是在泛型编程中使用的一些关键字和类型。

1)<T>表示一个类型参数,可以在类、接口或方法中使用。它允许在使用这些代码时指定一个具体的类型。例如,可以定义一个泛型类 List<T>,其中的 T 可以是任何类型,比如 List<Integer> 或 List<String>。T 是一个占位符,可以根据需要替换为任何类型。

2)<?>是一个无界通配符,也称为非特定类型。它用于表示一个未知类型的集合。与 <T> 不同,它不能用于定义新的泛型类型或方法。通常在方法参数中使用 <?> 表示可以接受任何类型的参数。

3)object是 Java 中的一个类,是所有类的超类。它可以代表任何对象,并且可以将任何对象赋值给 object 类型变量。但是,在将对象赋值给 object 类型变量时,会丢失对象的具体类型信息,因此需要进行类型转换才能使用对象的特定方法。

总结来说,<T>用于定义泛型类型或方法中的类型参数,<?>用于表示未知类型的集合或方法参数,而 object是所有类的超类,可以代表任何对象。

【在使用 < T >、<?> 和 object 时,需要注意强制类型转换的情况:】

<T>:在泛型类或泛型方法中使用 <T> 声明的类型参数,在使用时不需要进行强制类型转换。编译器会根据实际传入的类型进行类型检查和类型推断。

<?>:使用无界通配符 <?> 表示未知类型时,如果需要访问集合中的元素,通常需要进行强制类型转换。因为编译器无法确定集合中的元素的具体类型,所以在使用时需要将其转换为具体的类型。

object:object 是所有类的超类,可以代表任何对象。但是,当将一个具体类型的对象赋值给 object 类型的变量后,如果希望使用该对象的特定方法,就需要进行强制类型转换。

需要注意的是,在进行强制类型转换时,应该确保转换是安全的,避免出现类型转换异常(ClassCastException)。可以使用 instanceof 运算符来检查对象的类型,以确保类型转换的安全性。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值