容器【泛型类、泛型接口、泛型方法 、泛型方法与可变参数 】(一)-全面详解(学习总结---从入门到深化)

目录

 泛型(Generics)

泛型类

 泛型接口

泛型方法 

泛型方法与可变参数 


 泛型(Generics)

 为了能够更好的学习容器,我们首先要先来学习一个概念:泛型。
泛型基本概念,泛型是JDK5.0以后增加的新特性。
泛型的本质就是“数据类型的参数化”,处理的数据类型不是固定的,而是可以作为参数传入。我们可以把“泛型”理解为数据类型的一个占位符(类似:形式参数),即告诉编译器,在调用泛型时必须传入实际类型.

参数化类型,白话说就是:
  1.把类型当作是参数一样传递。
2. <数据类型> 只能是引用类型。

泛型的好处

在不使用泛型的情况下,我们可以使用Object类型来实现任意的参数类型,但是在使用时需要我们强制进行类型转换。这就要求程序员明确知道实际类型,不然可能引起类型转换错误;但是,在编译期我们无法识别这种错误,只能在运行期发现这种错误。使用泛型的好处就是可以在编译期就识别出这种错误,有了更好的安全性;同时,所有类型转换由编译器完成,在程序员看来都是自动转换的,提高了代码的可读性。

总结一下,就是使用泛型主要是两个好处:
1、代码可读性更好【不用强制转换】
2、程序更加安全【只要编译时期没有警告,运行时期就不会出现ClassCastException异常】

 类型擦除

编码时采用泛型写的类型参数,编译器会在编译时去掉,这称之为“类型擦除”。
泛型主要用于编译阶段,编译后生成的字节码class文件不包含泛型中的类型信息,涉及类型转换仍然是普通的强制类型转换。类型参数在编译后会被替换成Object,运行时虚拟机并不知道泛型。
泛型主要是方便了程序员的代码编写,以及更好的安全性检测。

 实时效果反馈
1.泛型是在JDK哪个版本中增加的新特性?
A  JDK5.0
B JDK6.0
C JDK7.0
D JDK8.0

2.泛型的本质是什么?
A 数据的参数化
B 对象的参数化
C 数据类型的参数化
D 基本类型的参数化

答案
1=>A 2=>C

泛型类

 泛型标记


定义泛型时,一般采用几个标记:E、T、K、V、N、?。他们约定
俗称的含义如下:

泛型标记  对应单词  说明
E Element 在容器中使用,表示容器中的元素
T Type 表示普通的JAVA类
K Key 表示键,例如:Map中的键Key
V Value 表示值
N Number 表示数值类型
?   表示不确定的JAVA类型

泛型类的使用

 语法结构

public class 类名<泛型标识符号> {  }

public class 类名<泛型标识符号,泛型标识符号> {  }

 示例

public class Generic<T> {
  private T  flag;
  public void setFlag(T flag){
    this.flag = flag;
 }
  public T getFlag(){
    return this.flag;
 }
}
public class Test {
  public static void main(String[] args) {

    //创建对象时,指定泛型具体类型。
    Generic<String> generic = new Generic<>();

    generic.setFlag("admin");

    String flag = generic.getFlag();
    System.out.println(flag);
   
    //创建对象时,指定泛型具体类型。
    Generic<Integer> generic1 = new Generic<>();

    generic1.setFlag(100);

    Integer flag1 = generic1.getFlag();
    System.out.println(flag1);
 }
}

实时效果反馈

1.如下哪个选项是正确定义泛型类的语法
A public class <泛型标识符号> 类名
B public <泛型标识符号> class 类名
C <泛型标识符号> public class 类名
D public class 类名<泛型标识符号>

答案
1=>D

 泛型接口

 泛型接口和泛型类的声明方式一致。

泛型接口的使用

语法结构

public interface 接口名<泛型标识符号> {   }
public interface 接口名<泛型标识符号,泛型标识符号>{   }

 示例

public interface IGeneric<T> {
  T getName(T name);
}



//在实现接口时传递具体数据类型
public class IgenericImpl implements
Igeneric<String> {
  @Override
  public String getName(String name) {
    return name;
 }
}


//在实现接口时仍然使用泛型作为数据类型
public class IGenericImpl2<T> implements
IGeneric<T>{
  @Override
  public T getName(T name) {
    return name;
 }
}

public class Test {
  public static void main(String[] args) {
    IGeneric<String> igeneric= new  IGenericImpl();
    String name = igeneric.getName("old");
    System.out.println(name);
    IGeneric<String> igeneric1 = new IGenericImpl2<>();
    String name1 = igeneric1.getName("it");
    System.out.println(name1);
 }
}

实时效果反馈
1.如下哪个选项是正确定义泛型接口的语法
A public interface<泛型标识符号> 接口名
B public <泛型标识符号> interface 接口名
C <泛型标识符号> public interface 接口名
D public interface 接口名<泛型标识符号>

答案
1=>D

泛型方法 

 类上定义的泛型,在方法中也可以使用。但是,我们经常需要仅仅在某一个方法上使用泛型,这时候可以使用泛型方法。
调用泛型方法时,不需要像泛型类那样告诉编译器是什么类型,编译器可以自动推断出类型

 泛型方法的使用


 非静态方法

非静态方法可以使用泛型类中所定义的泛型,也可以将泛型定义在方法上。

 语法结构

//无返回值方法
public <泛型标识符号> void getName(泛型标识符号name) {  }

//有返回值方法
public <泛型标识符号> 泛型标识符号 getName(泛型标识符号 name) {  }

 示例

public class MethodGeneric {
  public <T> void setName(T name){
    System.out.println(name);
 }
  public <T> T getAge(T age){
    return age;
 }
}
public class Test2 {
  public static void main(String[] args) {

    MethodGeneric methodGeneric = new MethodGeneric();

    methodGeneric.setName("old");

    Integer age = methodGeneric.getAge(123);

    System.out.println(age);
 }

静态方法

静态方法中使用泛型时有一种情况需要注意一下,那就是静态方法无法访问类上定义的泛型,所以必须要将泛型定义在方法上。

语法结构

//无返回值静态方法
public static <泛型标识符号> void setName(泛型标识符号 name){  }

//有返回值静态方法
public static <泛型标识符号> 泛型表示符号getName(泛型标识符号 name){  }

示例

public class MethodGeneric {
  public static <T> void setFlag(T flag){
    System.out.println(flag);
 }
  public static <T> T getFlag(T flag){
    return flag;
 }
}
public class Test4 {
  public static void main(String[] args) {

    MethodGeneric.setFlag("old");

    Integer flag1 =  MethodGeneric.getFlag(123123);

    System.out.println(flag1);
 }
}

实时效果反馈
1.如下哪个选项是正确定义泛型方法的语法
A <泛型标识符号> public void getName(泛型标识符号 name)
B public void <泛型标识符号> getName(泛型标识符号 name)
C public <泛型标识符号> void getName(泛型标识符号 name)
D public void getName <泛型标识符号>(泛型标识符号 name)

答案
1=>C

泛型方法与可变参数 

 在泛型方法中,泛型也可以定义可变参数类型。

语法结构

public <泛型标识符号> void showMsg(泛型标识符号... agrs){  }

示例

public class MethodGeneric {
  public <T> void method(T...args){

    for(T t:args){
      System.out.println(t);
     }

   }
}

public class Test5 {
  public static void main(String[] args) {
    MethodGeneric methodGeneric = new  MethodGeneric();

    String[] arr = new String[]{"a","b","c"};

    Integer[] arr2 = new Integer[]{1,2,3};

    methodGeneric.method(arr);

    methodGeneric.method(arr2);
  }
}

实时效果反馈
1.如下哪个选项是正确的在可变参数中使用泛型
A public <泛型标识符号> void showMsg(泛型标识符号... agrs)
B public void showMsg(<泛型标识符号>... agrs)
C public <泛型标识符号> void showMsg(<泛型标识符号>... agrs)

D public <泛型标识符号> void showMsg(Object... agrs)


答案
1=>A

猜你喜欢

转载自blog.csdn.net/m0_58719994/article/details/131669512