Java中泛型的介绍与简单使用

2024-08-28 16:08
文章标签 java 简单 使用 介绍 中泛

本文主要是介绍Java中泛型的介绍与简单使用,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

学习目标

掌握泛型的产生意义。
掌握泛型的基本使用。
了解泛型的警告信息及泛型的擦除。

泛型是在JDK1.5之后增加的内容,泛型(Generic)

使用泛型的原因


题目分析:
首先要考虑到,必须建立一好一个表示坐标点的类——Point,此类中有两个属性分别用来表示x坐标和y坐标,但是x和y中所保存的整数类型会有三种(int、float、String),而要想使用一个类型可以同时接收这样的三种类型数据,现在只能使用Object,因为Object类可以接收任何类型的数据,都会自动发生向上转型操作,这样三种数据类型安装以下的方式进行转换:
数字(int) —> 自动装箱成Interger —> 向上转型使用Object接收
小数(float)—> 自动装箱成Float —> 向上转型使用Object接收
字符串(String)—>向上转型使用Object接收

设计Point类
class Point{private Object x ;		// 表示X坐标private Object y ;		// 表示Y坐标public void setX(Object x){this.x = x ;}public void setY(Object y){this.y = y ;}public Object getX(){return this.x ;}public Object getY(){return this.y ;}
};public class GenericsDemo01{public static void main(String args[]){Point p = new Point() ;	// 声明一个Point的对象p.setX(10) ;		// 利用自动装箱操作:int --> Integer --> Objectp.setY(20) ;		// 利用自动装箱操作:int --> Integer --> Objectint x = (Integer)p.getX() ;	// 取出数据先变为Integer,之后自动拆箱int y = (Integer)p.getY() ;	// 取出数据先变为Integer,之后自动拆箱System.out.println("整数表示,X坐标为:" + x) ;System.out.println("整数表示,Y坐标为:" + y) ;}
};

小数表示
class Point{private Object x ;		// 表示X坐标private Object y ;		// 表示Y坐标public void setX(Object x){this.x = x ;}public void setY(Object y){this.y = y ;}public Object getX(){return this.x ;}public Object getY(){return this.y ;}
};public class GenericsDemo02{public static void main(String args[]){Point p = new Point() ;	// 声明一个Point的对象p.setX(10.5f) ;		// 利用自动装箱操作:float --> Float --> Objectp.setY(20.6f) ;		// 利用自动装箱操作:float --> Float --> Objectfloat x = (Float)p.getX() ;	// 取出数据先变为Float,之后自动拆箱float y = (Float)p.getY() ;	// 取出数据先变为Float,之后自动拆箱System.out.println("小数表示,X坐标为:" + x) ;System.out.println("小数表示,Y坐标为:" + y) ;}
};


字符串表示:
class Point{private Object x ;		// 表示X坐标private Object y ;		// 表示Y坐标public void setX(Object x){this.x = x ;}public void setY(Object y){this.y = y ;}public Object getX(){return this.x ;}public Object getY(){return this.y ;}
};public class GenericsDemo03{public static void main(String args[]){Point p = new Point() ;	// 声明一个Point的对象p.setX("东经180度") ;		// String --> Objectp.setY("北纬210度") ;		// String --> ObjectString x = (String)p.getX() ;	// 取出数据先变为String,之后自动拆箱String y = (String)p.getY() ;	// 取出数据先变为String,之后自动拆箱System.out.println("字符串表示,X坐标为:" + x) ;System.out.println("字符串表示,Y坐标为:" + y) ;}
};

以上代码存在很大问题,如果现在假设有以下的程序代码。
class Point{private Object x ;		// 表示X坐标private Object y ;		// 表示Y坐标public void setX(Object x){this.x = x ;}public void setY(Object y){this.y = y ;}public Object getX(){return this.x ;}public Object getY(){return this.y ;}
};public class GenericsDemo04{public static void main(String args[]){Point p = new Point() ;	// 声明一个Point的对象p.setX(10) ;			// 利用自动装箱操作:int --> Integer --> Objectp.setY("北纬210度") ;		// String --> Objectint x = (Integer)p.getX() ;	// 取出数据先变为Integer,之后自动拆箱int y = (Integer)p.getY() ;	// 取出数据先变为Integer,之后自动拆箱System.out.println("整数表示,X坐标为:" + x) ;System.out.println("整数表示,Y坐标为:" + y) ;}
};


传统的实现方法就有可能出现操作不当的情况,本程序就是数据类型不统一造成的。
认识泛型

泛型的使用

泛型可以解决数据类型的安全性问题,它主要的原理,是在类声明的时候通过一个标识表示类中某个属性的类型或者是某个方法的返回值以及参数类型。这样在类声明或实例化的时候只要指定好需要的类型即可。
泛型的定义格式如下:
 [访问权限] class 类名称<泛型类型1,泛型类型2,......泛型类型3>{
    [访问权限] 泛型类型标识 变量名称;
    [访问权限] 泛型类型标识  方法名称(){ };
    [访问权限]  返回值类型声明 方法名称(泛型类型标识 变量名称){};
}
泛型对象的定义
类名称<具体类型> 对象名称 = new 类名称<具体类型>();

按照此格式定义一个Point类。
class Point<T>{		// 此处可以随便写标识符号,T是type的简称private T var ;	// var的类型由T指定,即:由外部指定public T getVar(){	// 返回值的类型由外部决定return var ;}public void setVar(T var){	// 设置的类型也由外部决定this.var = var ;}
};

写完之后,就可以在对象声明的时候使用了。
class Point<T>{		// 此处可以随便写标识符号,T是type的简称private T var ;	// var的类型由T指定,即:由外部指定public T getVar(){	// 返回值的类型由外部决定return var ;}public void setVar(T var){	// 设置的类型也由外部决定this.var = var ;}
};
public class GenericsDemo06{public static void main(String args[]){Point<String> p = new Point<String>() ;	// 里面的var类型为String类型p.setVar("MLDN") ;		// 设置字符串System.out.println(p.getVar().length()) ;	// 取得字符串的长度}
};

以上是将var变量设置成了String类型,当然也可以设置成Integer,如果设置的内容与指定的泛型类型不一致,则会在编译时就出现错误。
class Point<T>{		// 此处可以随便写标识符号,T是type的简称private T var ;	// var的类型由T指定,即:由外部指定public T getVar(){	// 返回值的类型由外部决定return var ;}public void setVar(T var){	// 设置的类型也由外部决定this.var = var ;}
};
public class GenericsDemo07{public static void main(String args[]){Point<Integer> p = new Point<Integer>() ;	// 里面的var类型为String类型p.setVar("MLDN") ;		// 设置字符串}
};


这样可以更好的去保护数据类型。
 通过泛型就可以直接去修改之前的程序。
class Point<T>{private T x ;		// 表示X坐标private T y ;		// 表示Y坐标public void setX(T x){this.x = x ;}public void setY(T y){this.y = y ;}public T getX(){return this.x ;}public T getY(){return this.y ;}
};public class GenericsPoint{public static void main(String args[]){Point<Integer> p = new Point<Integer>() ;p.setX(10) ;		// 利用自动装箱操作:int --> Integerp.setY(20) ;		// 利用自动装箱操作:int --> Integerint x = p.getX() ;	// 自动拆箱int y = p.getY() ;	// 自动拆箱System.out.println("整数表示,X坐标为:" + x) ;System.out.println("整数表示,Y坐标为:" + y) ;}
};
在这样程序里,减少类类型转换的操作代码,而且更加安全,如果设置的内容不是数字,则在编译的时候就会出现错误,如下所示:
class Point<T>{private T x ;		// 表示X坐标private T y ;		// 表示Y坐标public void setX(T x){this.x = x ;}public void setY(T y){this.y = y ;}public T getX(){return this.x ;}public T getY(){return this.y ;}
};public class GenericsPoint{public static void main(String args[]){Point<Integer> p = new Point<Integer>() ;p.setX(10) ;		// 利用自动装箱操作:int --> Integerp.setY("北纬210度") ;		// 利用自动装箱操作:int --> Integerint x = p.getX() ;	// 自动拆箱int y = p.getY() ;	// 自动拆箱System.out.println("整数表示,X坐标为:" + x) ;System.out.println("整数表示,Y坐标为:" + y) ;}
};


泛型也可以在构造方法中使用,一般有可能使用构造方法为类中的属性赋值。

构造方法中使用泛型

构造方法可以为类中的属性初始化,那么如果类中的属性通过泛型指定 而又需要通过构造设置属性内容的时候,那么构造方法的定义与之前并无不同,不需要像声明类那样指定泛型。
使用格式:
[访问权限] 构造方法 ([<泛型类型>  参数名称]){ }
 例如:
class Point<T>{		// 此处可以随便写标识符号,T是type的简称private T var ;	// var的类型由T指定,即:由外部指定public Point(T var){		// 通过构造方法设置内容this.var = var ;}public T getVar(){	// 返回值的类型由外部决定return var ;}public void setVar(T var){	// 设置的类型也由外部决定this.var = var ;}
};
public class GenericsDemo08{public static void main(String args[]){Point<String> p = new Point<String>("liuxun") ;	// 里面的var类型为String类型System.out.println("内容:" + p.getVar()) ;}
};

在泛型中也可以指定多个泛型。

设置多个泛型,实例如下:
class Notepad<K,V>{		// 此处指定了两个泛型类型private K key ;		// 此变量的类型由外部决定private V value ;	// 此变量的类型由外部决定public K getKey(){return this.key ;}public V getValue(){return this.value ;}public void setKey(K key){this.key = key ;}public void setValue(V value){this.value = value ;}
};
public class GenericsDemo09{public static void main(String args[]){Notepad<String,Integer> t = null ;		// 定义两个泛型类型的对象t = new Notepad<String,Integer>() ;		// 里面的key为String,value为Integert.setKey("刘勋") ;		// 设置第一个内容t.setValue(22) ;			// 设置第二个内容System.out.print("姓名;" + t.getKey()) ;		// 取得信息System.out.print(",年龄;" + t.getValue()) ;		// 取得信息}
};



泛型的安全警告

在泛型应用中最好在声明类对象的时候指定好其内部的数据类型,例如"Info<String>" ,但也可以不指定类型。
class Info<T>{private T var ;public T getVar(){return this.var ;}public void setVar(T var){this.var = var ;}public String toString(){		// 覆写Object类中的toString()方法return this.var.toString() ;}
};
public class GenericsDemo10{public static void main(String args[]){Info i = new Info() ;		// 警告,没有指定泛型类型i.setVar("MLDN") ;			// 设置字符串System.out.println("内容:" + i.getVar()) ;}
};


在Info类中并没有指定泛型的类型,则在Java中为了保证程序依然可以使用,会将T设置成Object类型,这样一来,就可以接收任何的数据类型,也就是说此时var的类型是Object,所有的泛型信息将被擦除,实际上,以上的程序就相当于以下的定义格式:
class Info<T>{private T var ;public T getVar(){return this.var ;}public void setVar(T var){this.var = var ;}public String toString(){		// 覆写Object类中的toString()方法return this.var.toString() ;}
};
public class GenericsDemo11{public static void main(String args[]){Info<Object> i = new Info<Object>() ;		// 指定Object为泛型类型i.setVar("MLDN") ;			// 设置字符串System.out.println("内容:" + i.getVar()) ;}
};

泛型的安全警告
在泛型应用中最好在声明类的时候指定其内部的数据类型,例如:"Info<String>",但也可以不指定类型,这样一来用户在使用这样的类的时候就会出现不安全的警告信息,如下图:



总结:
1、泛型的产生意义:为了保证数据的安全性。
2、泛型的基本使用,由外部指定的其具体操作类型。

这篇关于Java中泛型的介绍与简单使用的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1115244

相关文章

JVM 的类初始化机制

前言 当你在 Java 程序中new对象时,有没有考虑过 JVM 是如何把静态的字节码(byte code)转化为运行时对象的呢,这个问题看似简单,但清楚的同学相信也不会太多,这篇文章首先介绍 JVM 类初始化的机制,然后给出几个易出错的实例来分析,帮助大家更好理解这个知识点。 JVM 将字节码转化为运行时对象分为三个阶段,分别是:loading 、Linking、initialization

Spring Security 基于表达式的权限控制

前言 spring security 3.0已经可以使用spring el表达式来控制授权,允许在表达式中使用复杂的布尔逻辑来控制访问的权限。 常见的表达式 Spring Security可用表达式对象的基类是SecurityExpressionRoot。 表达式描述hasRole([role])用户拥有制定的角色时返回true (Spring security默认会带有ROLE_前缀),去

浅析Spring Security认证过程

类图 为了方便理解Spring Security认证流程,特意画了如下的类图,包含相关的核心认证类 概述 核心验证器 AuthenticationManager 该对象提供了认证方法的入口,接收一个Authentiaton对象作为参数; public interface AuthenticationManager {Authentication authenticate(Authenti

Spring Security--Architecture Overview

1 核心组件 这一节主要介绍一些在Spring Security中常见且核心的Java类,它们之间的依赖,构建起了整个框架。想要理解整个架构,最起码得对这些类眼熟。 1.1 SecurityContextHolder SecurityContextHolder用于存储安全上下文(security context)的信息。当前操作的用户是谁,该用户是否已经被认证,他拥有哪些角色权限…这些都被保

Spring Security基于数据库验证流程详解

Spring Security 校验流程图 相关解释说明(认真看哦) AbstractAuthenticationProcessingFilter 抽象类 /*** 调用 #requiresAuthentication(HttpServletRequest, HttpServletResponse) 决定是否需要进行验证操作。* 如果需要验证,则会调用 #attemptAuthentica

Spring Security 从入门到进阶系列教程

Spring Security 入门系列 《保护 Web 应用的安全》 《Spring-Security-入门(一):登录与退出》 《Spring-Security-入门(二):基于数据库验证》 《Spring-Security-入门(三):密码加密》 《Spring-Security-入门(四):自定义-Filter》 《Spring-Security-入门(五):在 Sprin

Java架构师知识体认识

源码分析 常用设计模式 Proxy代理模式Factory工厂模式Singleton单例模式Delegate委派模式Strategy策略模式Prototype原型模式Template模板模式 Spring5 beans 接口实例化代理Bean操作 Context Ioc容器设计原理及高级特性Aop设计原理Factorybean与Beanfactory Transaction 声明式事物

性能测试介绍

性能测试是一种测试方法,旨在评估系统、应用程序或组件在现实场景中的性能表现和可靠性。它通常用于衡量系统在不同负载条件下的响应时间、吞吐量、资源利用率、稳定性和可扩展性等关键指标。 为什么要进行性能测试 通过性能测试,可以确定系统是否能够满足预期的性能要求,找出性能瓶颈和潜在的问题,并进行优化和调整。 发现性能瓶颈:性能测试可以帮助发现系统的性能瓶颈,即系统在高负载或高并发情况下可能出现的问题

中文分词jieba库的使用与实景应用(一)

知识星球:https://articles.zsxq.com/id_fxvgc803qmr2.html 目录 一.定义: 精确模式(默认模式): 全模式: 搜索引擎模式: paddle 模式(基于深度学习的分词模式): 二 自定义词典 三.文本解析   调整词出现的频率 四. 关键词提取 A. 基于TF-IDF算法的关键词提取 B. 基于TextRank算法的关键词提取

水位雨量在线监测系统概述及应用介绍

在当今社会,随着科技的飞速发展,各种智能监测系统已成为保障公共安全、促进资源管理和环境保护的重要工具。其中,水位雨量在线监测系统作为自然灾害预警、水资源管理及水利工程运行的关键技术,其重要性不言而喻。 一、水位雨量在线监测系统的基本原理 水位雨量在线监测系统主要由数据采集单元、数据传输网络、数据处理中心及用户终端四大部分构成,形成了一个完整的闭环系统。 数据采集单元:这是系统的“眼睛”,