六、java高级-泛型(一)

六、泛型

1、泛型

从什么是泛型、泛型从何而来、泛型出现是为了解决什么问题、功能及作用说泛型

1.1什么是泛型?

泛型:即“参数化类型”,也就是将需要操作对象的类型进行参数化。在编写代码的时候,不必声明操作对象(函数、类、接口和方法等)的类型,而是在使用时在确定,并且可以在编译时检查类型是否匹配。

泛型就好比标记容器的一个标签,而容器可以容纳各种类型的数据,泛型就用于标记容器可以容纳那种类型的数据,但具体放入什么样的数据需要在使用时确定。比如说,这个容器他就是用来盛放调料的,一个调料瓶用来装盐贴个贴纸标记好,一个用来装辣椒写上辣椒用贴纸标记好。再比如,泛型在用于集合中,ArrayList< String >只能用于处理String类型的元素,ArrayList< Integer>只能处理数值类型的元素。

  • 格式:< E > 、< T >只能指定引用类型,不能指定为基本数据类型/void
【修饰符】 class 类名<类型变量列表>extends 父类】 【implements 父接口们】{
    
}
【修饰符】 interface 接口名<类型变量列表>implements 父接口们】{
    
}
【修饰符】 <类型变量列表> 返回值类型 方法名(【形参列表】)throws 异常列表】{
    //...
}

eg:
public class ArrayList<E>    
public interface Map<K,V>{
    ....
} 
//java.util.Arrays类中的
public static <T> List<T> asList(T... a){
    ....
}
1.2 泛型从何而来?

泛型是从jdk1.5开始引入的。泛型的引用大大提高了代码的复用性,使得在编写代码的时候可以不必重复编写对不同类型的数据的操作。和数据结构最开始介绍的抽象数据类型(ADT)和参数化类型一个道理。ADT中允许程序员定义数据类型的抽象形式及该数据类型相关的操作,而不必暴露其内部实现。参数化类型则允许类型或数据结构的行为根据传入的参数类型而变化。

以add()方法举例:

public void add(){
    int a;
    int b;
    System.out.println(a+b);
}

如果我要使用上述的add()方法,怎么让我需要处理的数据传递进去呢?由此引入了形参和实参的概念。方法体功能的具体实现,需要外界提供具体的数据,在调用这个方法时,方法里面的参数值才能确定。

方法定义时,可以指定一个或多个参数,用于接收调用该方法时传递的数据。这些参数可以是基本类型(如整数、浮点数等)或对象类型(如字符串、自定义对象等)。当调用方法时,传递的数据会被赋值给这些参数,方法内部可以通过这些参数来访问和处理数据。

public void add(int a,int b){
    int a;
    int b;
    System.out.println(a+b);
}

而泛型是如何传递数据的呢

  • 一样的道理→参数类型、返回值

在泛型中,参数化类型(即泛型类型)是在定义方法或类时指定的,而不是在调用时指定的。因此,泛型方法或泛型类在定义时可以包含形式参数(泛型参数),这些参数用于表示方法或类中的类型。在调用泛型方法或实例化泛型类时,可以为这些形式参数提供实际的类型参数,以确定方法或类中所使用的具体类型。

public <T> void printData(T data) {
    System.out.println(data);
}

// 调用泛型方法,并传递不同类型的数据
printData("Hello"); // T 被实例化为 String 类型
printData(123);     // T 被实例化为 Integer 类型
1.3 泛型的出现是为了解决什么问题呢?

(俺学到集合这里便以集合举例)

1、数据类型匹配问题

我们都知道集合可以存储多种数据类型,实际上ArrayList内部就是一个Object[],数组在用foreach迭代时,迭代的对象的数据类型时objetc。在传入数据时很容易出错,不方便。

ArrayList arr1 = new ArrayList();
arr1.add("zhangsan");
arr1.add("lisi");
arr1.add("wangwu");
arr1.add("xiaoming");
arr1.add(new Integer(123));
for (Object o : arr1) {

}

2、强制转换问题

并且如果需要获取到Object,必须进行强制转型为String,并且容易出现错误。

String s1 = (String) arr1.get(0);
String s2 = (String) arr1.get(4);//ClassCastException

解决办法:

  1. 为每种数据类型单独编写→代码重复高
  2. 泛型:泛型就是定义一种模板,例如ArrayList,然后在代码中为用到的类创建对应的ArrayList<类型>
ArrayList<String> arr2 = new ArrList();
arr2.add("hello");
arr2.add(1);//报错
for(String s : arr2){
	System.out.println(s);
}
1.4 功能及作用
  1. 代码重用和灵活性: 可以处理多种不同类型的数据
  2. 类型安全和错误检测: 可以在编译时进行类型检查,防止数据不匹配问题
  3. **减少类型转换和异常:**编译器可以自动处理类型转换
  4. 提高性能: 泛型在编译时或运行时会进行类型擦除或优化处理,以提高代码的性能。例如,Java中的类型擦除会将泛型代码转换为非泛型的形式,以提高代码的执行效率。

你可能感兴趣的:(Java,java)