当前位置:   article > 正文

Java泛型_java 泛型字段

java 泛型字段

目录

泛型定义的语法

一、泛型类

语法

自定义示例

注意 

二、泛型接口

语法

泛型接口使用分两种情况 

三、泛型方法

语法 

示例

特殊的泛型

泛型使用的语法

特性


泛型即——“参数化类型

它允许我们定义一个类、接口或方法,使它们可以接受指定类型的参数,从而提高了代码的复用性和安全性。

泛型定义的语法

一、泛型类

泛型定义在类上的时候,整个类都可以使用泛型(除了静态的)

比如:List、Set、Map..

语法

  1. class 类名 <泛型标识符>{
  2. }

自定义示例

  1. public class Student<T, U> {
  2. private T name;
  3. private U age;
  4. public Student(T name, U age) {
  5. this.name= name;
  6. this.age= age;
  7. }
  8. public T getName() {
  9. return name;
  10. }
  11. public U getAge() {
  12. return age;
  13. }
  14. public void setName(T name) {
  15. this.name= name;
  16. }
  17. public void setAge(U age) {
  18. this.age= age;
  19. }
  20. }

    在上面的代码中,我们定义了一个泛型类Student   <T, U> ,其中T,和U是类型参数。Student类,第一个值的类型是T,第二个值的类型是U。

        在Student类的构造函数和方法中,我们可以使用类型参数T和U,从而实现了通用性。

例如:

  1. Student<String, Integer> student= new student<>("BroRiver", 20);
  2. String s = student.getName();
  3. Integer i = student.getAge();

      在上面的代码中,我们创建了一个Student  <String, Integer>对象,表示该对中的第一个值是字符串类型,第二个值是整数类型。

        get我们可以使用get方法来获取该对中的值,并在不需要进行类型转换的情况下使用它们。

自定义泛型类可以让我们在定义类时指定类型参数,从而实现通用性和可重用性。 

注意 

1、泛型的类型参数只能是类类型,不能是基本数据类型

2、不能对加泛型的类类型使用instanceof操作,编译时不会通过


二、泛型接口

语法

  1. interface 接口名<标识>{
  2. }

泛型接口使用分两种情况 

        定义泛型接口

  1. public interface MyInterface<T>{
  2. public T next();
  3. }

        1.未传入泛型实参

  1. //通用类
  2. public class MyGenericClass<T> implements MyInterface<T> {
  3. @Override
  4. public T next() {
  5. return null;
  6. }
  7. }

        2.传入泛型实参

  1. //指定String
  2. public class MyStringClass implements MyInterface<String> {
  3. @Override
  4. public String next() {
  5. return “hello world”;
  6. }
  7. }

        类实现了一个泛型接口,在类名后面传入了一个具体的泛型实参String

三、泛型方法

泛型方法要比前面两个更复杂

首先我们要清楚一点:【泛型方法和泛型类当中的方法,是不一样的概念】

1、只有当方法中使用了泛型类型参数时,该方法才是泛型方法

2、泛型类或泛型接口中的方法,是没有定义泛型的,它们是使用定义在类或接口上的范型。

3、普通类可以定义泛型方法;泛型类也可以定义泛型方法,但是要换一个标识。

语法 

  1. 修饰符 <T> 返回类型 方法名(形参列表){
  2. }

只有声明<T>的方法才是泛型方法

示例

  1. public class ArrayUtils {
  2. public static <T> void printArray(T[] array) {
  3. for (T element : array) {
  4. System.out.print(element + " ");
  5. }
  6. System.out.println();
  7. }
  8. }

        在上面的示例中,printArray()是一个泛型方法,它接受一个泛型数组作为参数,并将数组中的元素打印出来。<T>是类型参数列表,用于定义泛型类型参数,它可以在方法的返回值类型、参数类型等位置使用。在方法内部,我们使用了for循环遍历数组,并使用System.out.print()方法打印每个元素。

      泛型方法,可以接受不同类型的数组作为参数,从而实现了代码的重用。  

特殊的泛型

1、可以一次性定义多个泛型标识,中间用逗号分隔 形如:<K,V,T>

2、可以指定传入的范型的边界,比如它是谁的子类; 形如:<T extends 父类> 当我们这么做的时候,就可以在代码中用T的对象,调用父类的可见方法了。

3、也可以指定多个边界,比如T必须继承谁,同时要实现哪些接口。 语法:<T extends 父类 & 接口1 & 接口2>

注意:

如果要指定T的父类是谁,只能写一个,且是第一个; 如果要指定T的接口,不指定父类,那么顺序无所谓。

泛型使用的语法

1、在给泛型指定数据类型的时候,不能是基本数据类型

2、如果在使用的时候没有给泛型指定数据类型,那么它会默认为Object类型;

3、JDK11中不能使用 instanceof 判断 某个对象是否属于某个类的带泛型类型;JDK17允许了。

gc instanceof GenericClass<String>

4、类型推断【当我们调用一个泛型方法时,如果方法的参数类型是一个泛型类型,那么编译器就可以根据该参数的实际类型推断出泛型类型】

5、在使用泛型的时候,还有一种特殊语法叫做:通配符与上下边界

  • 通配符与上边界 <? extends A类> 这个标识表示,这里能够是A类及其所有子类的对象;
  • 通配符与下边界 <? super B类> 这个标识标识,这里能够是B类及其基类。

特性

        Java的泛型被称为“伪泛型”,说白了它就是一个语法糖,只能影响编译器(无法影响运行期)。

泛型相对于Java虚拟机来说是透明的,编译器编译后生成的二进制代码有没有泛型都是一样的。

类型擦除

        类型擦除是指在编译器编译泛型代码时,将所有 泛型类型 替换成其 对应的边界类型Object类型,从而生成字节码文件。

        这样做是为了保持Java语言的向后兼容性,因为泛型是在Java 5中引入的,而Java 5之前的版本并不支持泛型。

        类型擦除的结果是,在运行时无法访问泛型类型的具体信息,例如泛型类型参数的实际类型、边界类型等。

示例:

  1. public class GenericClass<T> {
  2. private T value;
  3. public void setValue(T value) {
  4. this.value = value;
  5. }
  6. public T getValue() {
  7. return value;
  8. }
  9. }

        在上面的示例中,GenericClass 是一个泛型类,它的类型参数为T。

        在编译时,由于类型擦除的原因,T将被替换成Object类型,所以实际上value字段的类型是Object,而get、set方法的参数和返回值类型也是Object。这意味着,无论我们在运行时将GenericClass 实例化成什么样的类型,它们都将具有相同的字节码,只是字段和方法的参数和返回值的类型不同。这也是类型擦除的一个副作用,即无法在运行时访问泛型类型参数的具体信息。

声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号