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

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

泛型(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 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


目录
相关文章
|
8天前
|
移动开发 HTML5 容器
Twaver-HTML5基础学习(21)网元管理容器(ElementBox)
本文介绍了Twaver HTML5中的网元管理容器(ElementBox),包括如何监听网元属性变化、容器属性变化、网元元素变化以及数据层次变化。文章通过示例代码展示了如何使用不同的事件监听方法来响应这些变化,并通过控制台输出相关的事件信息。
25 4
Twaver-HTML5基础学习(21)网元管理容器(ElementBox)
|
8天前
|
移动开发 前端开发 HTML5
Twaver-HTML5基础学习(23)页管理容器(TabBox)、选中模型(SelectionModel)
本文介绍了Twaver HTML5中的页管理容器(TabBox)和选中模型(SelectionModel)。文章解释了如何使用TabBox来管理Tab页,并通过示例代码展示了SelectionModel的多种功能,包括追加选中元素、设置选中元素、选中所有元素、移除元素选中状态、清除所有选中状态等。此外,还介绍了如何监听选中状态的变化事件以及如何设置不同的选中模式,如多选、单选和不可选。
23 2
Twaver-HTML5基础学习(23)页管理容器(TabBox)、选中模型(SelectionModel)
|
6天前
|
Kubernetes API Docker
跟着iLogtail学习容器运行时与K8s下日志采集方案
iLogtail 作为开源可观测数据采集器,对 Kubernetes 环境下日志采集有着非常好的支持,本文跟随 iLogtail 的脚步,了解容器运行时与 K8s 下日志数据采集原理。
|
8天前
|
移动开发 数据管理 HTML5
Twaver-HTML5基础学习(22)层管理容器(LayerBox)、告警管理容器(AlarmBox)、列管理容器(ColumnBox)、属性管理容器(PropertyBox)
本文介绍了Twaver HTML5中的多种管理容器:层管理容器(LayerBox)、告警管理容器(AlarmBox)、列管理容器(ColumnBox)和属性管理容器(PropertyBox)。文章解释了这些容器的作用、如何获取它们,并提供了一些基本的操作方法。这些容器分别用于管理图层、告警、表格列和属性对象,是TWaver中数据管理和组织的重要部分。
22 1
|
19天前
|
弹性计算 运维 持续交付
探索Docker容器化技术及其在生产环境中的应用
探索Docker容器化技术及其在生产环境中的应用
68 5
|
12天前
|
Linux iOS开发 Docker
Docker:容器化技术的领航者 —— 从基础到实践的全面解析
在云计算与微服务架构日益盛行的今天,Docker作为容器化技术的佼佼者,正引领着一场软件开发与部署的革命。它不仅极大地提升了应用部署的灵活性与效率,还为持续集成/持续部署(CI/CD)提供了强有力的支撑。
192 69
|
2天前
|
Kubernetes Cloud Native Docker
云原生时代的容器化实践:Docker与Kubernetes入门
【9月更文挑战第30天】在云计算的浪潮中,云原生技术正以前所未有的速度重塑着软件开发和运维领域。本文将通过深入浅出的方式,带你了解云原生的核心组件——Docker容器和Kubernetes集群,并探索它们如何助力现代应用的构建、部署和管理。从Docker的基本命令到Kubernetes的资源调度,我们将一起开启云原生技术的奇妙之旅。
|
12天前
|
运维 Cloud Native Docker
云原生技术入门:Docker容器化实战
【9月更文挑战第20天】本文将引导你走进云原生技术的世界,通过Docker容器化技术的实战演练,深入理解其背后的原理和应用。我们将一起探索如何在云平台上利用Docker简化部署、扩展和管理应用程序的过程,并揭示这一技术如何改变现代软件的开发和运维模式。
|
7天前
|
Cloud Native 持续交付 Docker
云原生技术入门与实践:Docker容器化部署示例
【9月更文挑战第25天】在数字化转型的浪潮下,云原生技术成为推动企业创新的重要力量。本文旨在通过浅显易懂的语言,为初学者揭示云原生技术的核心概念及其应用价值。我们将以Docker容器为例,逐步引导读者了解如何将应用程序容器化,并在云端高效运行。这不仅是对技术趋势的跟随,更是对资源利用和开发效率提升的探索。
26 4
|
1月前
|
NoSQL 关系型数据库 Redis
mall在linux环境下的部署(基于Docker容器),Docker安装mysql、redis、nginx、rabbitmq、elasticsearch、logstash、kibana、mongo
mall在linux环境下的部署(基于Docker容器),docker安装mysql、redis、nginx、rabbitmq、elasticsearch、logstash、kibana、mongodb、minio详细教程,拉取镜像、运行容器
mall在linux环境下的部署(基于Docker容器),Docker安装mysql、redis、nginx、rabbitmq、elasticsearch、logstash、kibana、mongo
下一篇
无影云桌面