JAVA泛型详解

合集下载

Java泛型(泛型接口、泛型类、泛型方法)

Java泛型(泛型接口、泛型类、泛型方法)

Java泛型(泛型接⼝、泛型类、泛型⽅法)转载转载出处:泛型接⼝:定义⼀个泛型接⼝:通过类去实现这个泛型接⼝的时候指定泛型T的具体类型。

指定具体类型为Integer:指定具体类型为String:指定具体类型为⼀个⾃定义的对象:泛型类:在编译器,是⽆法知道K和V具体是什么类型,只有在运⾏时才会真正根据类型来构造和分配内存。

泛型⽅法:引⽤其他⼈写的,觉得不错:定义泛型⽅法时,必须在返回值前边加⼀个<T>,来声明这是⼀个泛型⽅法,持有⼀个泛型T,然后才可以⽤泛型T作为⽅法的返回值。

Class<T>的作⽤就是指明泛型的具体类型,⽽Class<T>类型的变量c,可以⽤来创建泛型类的对象。

为什么要⽤变量c来创建对象呢?既然是泛型⽅法,就代表着我们不知道具体的类型是什么,也不知道构造⽅法如何,因此没有办法去new⼀个对象,但可以利⽤变量c的newInstance⽅法去创建对象,也就是利⽤反射创建对象。

泛型⽅法要求的参数是Class<T>类型,⽽Class.forName()⽅法的返回值也是Class<T>,因此可以⽤Class.forName()作为参数。

其中,forName()⽅法中的参数是何种类型,返回的Class<T>就是何种类型。

在本例中,forName()⽅法中传⼊的是User类的完整路径,因此返回的是Class<User>类型的对象,因此调⽤泛型⽅法时,变量c的类型就是Class<User>,因此泛型⽅法中的泛型T就被指明为User,因此变量obj的类型为User。

当然,泛型⽅法不是仅仅可以有⼀个参数Class<T>,可以根据需要添加其他参数。

为什么要使⽤泛型⽅法呢?因为泛型类要在实例化的时候就指明类型,如果想换⼀种类型,不得不重新new⼀次,可能不够灵活;⽽泛型⽅法可以在调⽤的时候指明类型,更加灵活。

Java泛型总结

Java泛型总结

Java泛型总结1. 什么是泛型?泛型(Generic type 或者generics)是对Java 语言的类型系统的一种扩展,以支持创建可以按类型进行参数化的类。

可以把类型参数看作是使用参数化类型时指定的类型的一个占位符,就像方法的形式参数是运行时传递的值的占位符一样。

可以在集合框架(Collection framework)中看到泛型的动机。

例如,Map 类允许您向一个Map 添加任意类的对象,即使最常见的情况是在给定映射(map)中保存某个特定类型(比如String)的对象。

因为Map.get() 被定义为返回Object,所以一般必须将Map.get() 的结果强制类型转换为期望的类型,如下面的代码所示:Map m = new HashMap();m.put("key", "blarg");String s = (String) m.get("key");要让程序通过编译,必须将get() 的结果强制类型转换为String,并且希望结果真的是一个String。

但是有可能某人已经在该映射中保存了不是String 的东西,这样的话,上面的代码将会抛出ClassCastException。

理想情况下,您可能会得出这样一个观点,即m 是一个Map,它将String 键映射到String 值。

这可以让您消除代码中的强制类型转换,同时获得一个附加的类型检查层,该检查层可以防止有人将错误类型的键或值保存在集合中。

这就是泛型所做的工作。

2. 泛型的好处Java 语言中引入泛型是一个较大的功能增强。

不仅语言、类型系统和编译器有了较大的变化,以支持泛型,而且类库也进行了大翻修,所以许多重要的类,比如集合框架,都已经成为泛型化的了。

这带来了很多好处:类型安全。

泛型的主要目标是提高Java 程序的类型安全。

通过知道使用泛型定义的变量的类型限制,编译器可以在一个高得多的程度上验证类型假设。

java 方法的泛型

java 方法的泛型

java 方法的泛型Java方法的泛型泛型(Generics)是Java语言中一个强大的特性,它允许我们在编译时期检测类型的一致性,并且提供了更加灵活和安全的代码重用方式。

泛型在Java 5中引入,成为Java语言的一大亮点。

在本文中,我将介绍Java方法中的泛型的使用方法和注意事项。

一、泛型方法的定义和语法泛型方法是一种在方法中使用泛型类型参数的方法。

在方法的返回类型之前使用尖括号,尖括号中指定泛型类型参数。

例如,下面是一个简单的泛型方法的定义:```javapublic <T> void printArray(T[] arr) {for (T element : arr) {System.out.print(element + " ");}System.out.println();}```在上面的例子中,泛型方法printArray使用了一个类型参数T,它表示任意类型。

方法的参数arr是一个泛型数组,类型为T[]。

在方法的实现中,我们可以像操作普通数组一样遍历和处理泛型数组。

二、调用泛型方法调用泛型方法时,可以明确指定泛型类型参数,也可以根据方法参数的类型推断出泛型类型参数。

例如,下面是两种调用泛型方法的方式:```javaString[] strArr = {"Java", "Python", "C++"};printArray(strArr); // 调用泛型方法,类型参数自动推断为StringInteger[] intArr = {1, 2, 3, 4, 5};this.<Integer>printArray(intArr); // 显式指定泛型类型参数为Integer```从上面的例子中可以看出,我们既可以根据参数类型推断出泛型类型参数,也可以显式指定泛型类型参数。

这使得泛型方法在使用时非常灵活。

java 中 经典泛型例子

java 中 经典泛型例子

java 中经典泛型例子(原创版)目录一、泛型的概念二、泛型的好处三、泛型的使用示例四、泛型的注意事项正文一、泛型的概念泛型是一种编程语言中的特性,它允许你在编译时检查数据类型的一致性。

在 Java 中,泛型是一种强大的功能,它可以让你在创建数据结构时指定数据的类型,从而提高代码的重用性和类型安全。

二、泛型的好处泛型的好处主要有两点:1.类型安全:泛型可以避免运行时的类型转换错误。

在使用泛型之前,如果你想要创建一个可容纳不同类型对象的集合,你需要使用 Object 类型。

但是,这会导致在运行时出现类型转换错误。

泛型可以解决这个问题,因为它允许你在编译时指定数据的类型。

2.代码重用:泛型可以提高代码的重用性。

当你需要创建多个不同类型的集合时,你可以使用泛型来创建一个通用的集合类,然后在需要时为不同的类型创建不同的实例。

三、泛型的使用示例下面是一个使用泛型的简单示例:```javaimport java.util.ArrayList;import java.util.List;public class GenericsExample {public static void main(String[] args) {List<String> stringList = new ArrayList<>();stringList.add("Hello");stringList.add("World");List<Integer> integerList = new ArrayList<>();integerList.add(42);integerList.add(17);}}```在这个示例中,我们使用泛型来创建了两个不同的集合,一个用于存储字符串,另一个用于存储整数。

这样可以确保在编译时检查类型一致性,避免运行时的类型转换错误。

java泛型的理解

java泛型的理解

java泛型的理解摘要:1.泛型的概念2.泛型的作用3.泛型的使用4.泛型的注意事项正文:一、泛型的概念Java 泛型是Java 语言在1.5 版本引入的一种新的特性,它的出现使得Java 在面向对象编程上更加强大和灵活。

泛型是一种将类型抽象化的手段,它允许我们编写可以适用于多种类型的代码,同时避免了强制类型转换所带来的潜在错误。

二、泛型的作用泛型的主要作用有以下几点:1.提高代码的复用性:使用泛型可以编写一次代码,然后在不同的类型情况下重复使用,避免了重复编写代码的繁琐。

2.类型安全:泛型可以在编译时检查类型是否匹配,避免了运行时的类型转换错误。

3.提高代码的可读性:通过使用泛型,可以使代码更加简洁明了,减少了类型相关的繁琐描述。

三、泛型的使用在Java 中,泛型的使用非常简单。

只需要在类名或者方法名后面跟上尖括号<>,其中尖括号内是一个或多个类型参数。

例如:```javaList<String> list = new ArrayList<>(); // 使用泛型创建一个字符串列表list.add("hello");```四、泛型的注意事项在使用泛型时,需要注意以下几点:1.泛型擦除:Java 中的泛型实际上是一种“伪泛型”,它只在编译时起作用。

在运行时,泛型信息会被擦除,因此无法通过泛型类型实例化对象。

2.类型参数的限制:泛型的类型参数必须继承自一个共同的基类,或者实现一个共同的接口。

3.不能实例化泛型类型:由于泛型擦除,我们不能创建泛型类型的实例,只能通过泛型类型来创建具体的类型实例。

java泛型

java泛型

1 java中泛型Java中的泛型–泛型是Java SE 1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。

–这种参数类型可以用在类、接口和方法的创建中,分别称为泛型类、泛型接口、泛型方法。

Java语言引入泛型的好处是安全简单Class ArrayList<E>:声明一个泛型类ArrayList,其中E可以使用任意一个具体类型替代,泛型类型往往使用一个大写字母表示。

public boolean add(E o):E是泛型,也就是说,使用add方法时,可以为其传递任意一种类型的参数。

其中此处的E是在类中定义的Java中泛型的作用:简单安全–在编译的时候检查类型安全,并且所有的强制转换都是自动和隐式的,提高代码的重用率。

–消除代码中的强制类型转换,同时获得一个附加的类型检查层,该检查层可以防止有人将错误类型的值保存在集合中泛型类指的是在定义一个类的时候,在类名处使用<E>的形式,标记该类中使用到泛型,也就是可以使用E来表示类中属性,方法参数等类型,使用时再具体指定是哪种具体类型。

声明类名后使用<E>(E可以是任何其他字母),即可以指定该类是一个泛型类类型参数可以在该类中需要数据类型的地方使用,如属性声明、方法声明等一个简单的泛型类泛型类最常见的应用是API中集合类。

public class Gen<E> {private E atr;public Gen(){}public E getAtr() {return atr;}public void setAtr(E atr) {this.atr = atr; }……方法也可以声明成泛型方法,只要在返回值前声明泛型参数列表即可泛型方法使得该方法能够独立于类而产生变化要定义泛型方法,只需将泛型参数列表置于返回值之前public <E> E getX(E x){return x;}注意:是否拥有泛型方法,与其所在的类是否泛型没有关系。

java jdk对泛型参数的解析

java jdk对泛型参数的解析

一、泛型的概念与作用泛型是Java编程语言的一个重要特性,它使得数据类型在定义时不必确定,而在使用时再确定。

泛型的作用在于提高代码的重用性、类型安全性和可读性。

在使用泛型时,可以在编译时发现类型不匹配的错误,从而避免了在运行时出现类型转换异常。

二、Java JDK中泛型的实现Java JDK中的泛型是通过类型擦除来实现的。

在编译时,泛型类型会被擦除为其上限类型或Object类型,在运行时并不保留泛型的实际类型信息。

这种方式可以保证向后兼容性,但也带来了一些限制和特殊情况。

三、泛型参数的使用与解析1. 泛型参数的声明与使用在Java中,泛型参数通常使用大写字母表示,如T、E、K、V等。

在声明泛型类、接口或方法时,需要在类型和方法名之间加上尖括号,并在其中声明泛型参数。

在使用泛型时,可以将具体的类型赋给泛型参数,以指定其实际类型。

2. 类型擦除对泛型参数的影响由于类型擦除的存在,在编译时编译器无法获取泛型的实际类型,因此在编译后的字节码中泛型参数的类型信息已经丢失。

这就导致了无法直接获取泛型参数的具体类型。

3. 通过反射获取泛型参数的实际类型在某些情况下,我们需要通过反射来获取泛型参数的实际类型。

通过反射可以绕过类型擦除的限制,获取泛型参数的实际类型信息。

这种方式虽然可以实现,但在实际应用中并不常见,因为它破坏了Java的类型安全机制。

4. 通配符类型与泛型参数除了直接声明泛型参数外,Java还提供了通配符类型来表示不确定的泛型参数。

通配符类型使用问号(?)表示,包括无界通配符、上界通配符和下界通配符。

通配符类型可以在某些情况下替代泛型参数,使得代码更为灵活。

四、泛型参数在集合框架中的应用1. 泛型参数与集合框架Java集合框架中广泛使用了泛型参数,通过泛型参数可以指定集合中元素的类型。

借助泛型参数,可以使得集合中的元素类型更加明确,从而提高代码的可读性和类型安全性。

2. 泛型参数的局限性在使用泛型参数时需要注意,Java中的泛型是不可变的。

java 泛型详解

java 泛型详解

java 泛型详解1. 概述泛型在java中有很重要的地位,在面向对象编程及各种设计模式中有非常广泛的应用。

什么是泛型?为什么要使用泛型?泛型,即“参数化类型”。

一提到参数,最熟悉的就是定义方法时有形参,然后调用此方法时传递实参。

那么参数化类型怎么理解呢?顾名思义,就是将类型由原来的具体的类型参数化,类似于方法中的变量参数,此时类型也定义成参数形式(可以称之为类型形参),然后在使用/调用时传入具体的类型(类型实参)。

泛型的本质是为了参数化类型(在不创建新的类型的情况下,通过泛型指定的不同类型来控制形参具体限制的类型)。

也就是说在泛型使用过程中,操作的数据类型被指定为一个参数,这种参数类型可以用在类、接口和方法中,分别被称为泛型类、泛型接口、泛型方法。

2.一个栗子一个被举了无数次的例子:List arrayList = new ArrayList();arrayList.add("aaaa");arrayList.add(100);for(int i = 0; i< arrayList.size();i++){String item = (String)arrayList.get(i);Log.d("泛型测试","item = " + item);}毫无疑问,程序的运行结果会以崩溃结束:ng.ClassCastException:ng.Integer cannot be cast to ng.String。

ArrayList可以存放任意类型,例子中添加了一个String类型,添加了一个Integer类型,再使用时都以String的方式使用,因此程序崩溃了。

为了解决类似这样的问题(在编译阶段就可以解决),泛型应运而生。

我们将第一行声明初始化list的代码更改一下,编译器会在编译阶段就能够帮我们发现类似这样的问题。

List<String> arrayList = new ArrayList<String>();...//arrayList.add(100); 在编译阶段,编译器就会报错3.特性泛型只在编译阶段有效。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

7.*泛型我们知道,使用变量之前要定义,定义一个变量时必须要指明它的数据类型,什么样的数据类型赋什么样的值。

下面我们先来看一个例子:假如我们现在要定义一个类来表示坐标,要求坐标的数据类型可以是整数、小数和字符串,例如:x=50,y=50x=37.13,y=169.35x="东经100度",y="北纬100度"针对不同的数据类型,除了借助方法重载,还可以借助自动封装和向上转型。

我们知道,基本数据类型可以自动装箱,被转换成对应的包装类;Object是所有类的父类,任何一个类的实例都可以向上转型为Object类型。

程序清单:1.public class DemoTest{2.public static void main(String[]args){3.Position p=new Position();4.p.setX(50);//int->Integer->Object5.p.setY(50);6.int x=(Integer)p.getX();//向下转型7.int y=(Integer)p.getY();8.System.out.println("This Position is:"+x+","+y);9.p.setX(37.13);//double->Double->Object10.p.setY("东经100度");11.double m=(Double)p.getX();//必须向下转型12.double n=(Double)p.getY();//运行期间抛出异常13.System.out.println("This Position is:"+m+","+n);14.}15.}16.class Position{17.Object x=0;18.Object y=0;19.//由于篇幅原因,这里省去setter和getter方法,请读者实验时自行加上20.}程序说明:上面的代码中,生成坐标时不会有任何问题,但是取出坐标时,要向下转型,但是向下转型存在着风险,而且编译期间不容易发现,只有在运行期间才会抛出异常,所以要尽量避免使用向下转型。

运行上面的代码,第12行会抛出ng.ClassCastException 异常。

那么,有没有更好的办法,既可以不使用重载(有重复代码),又能把风险降到最低呢?有,可以使用泛型类,它可以接受任意类型的数据。

所谓“泛型”,就是“宽泛的数据类型”,任意的数据类型。

泛型(Generic type或者generics)是对Java语言的类型系统的一种扩展,以支持创建可以按类型进行参数化的类。

可以把类型参数看作是使用参数化类型时指定的类型的一个占位符,就像方法的形式参数是运行时传递的值的占位符一样。

可以在集合框架(Collection framework)中看到泛型的动机。

Java语言中引入泛型是一个较大的功能增强﹐不仅语言、类型系统和编译器有了较大的变化,以支持泛型,而且类库也进行了大翻修,所以许多重要的类,比如集合框架,都已经成为泛型化的了。

这带来了很多好处:1.类型安全。

泛型的主要目标是提高Java程序的类型安全。

通过知道使用泛型定义的变量的类型限制,编译器可以在一个高得多的程度上验证类型假设。

没有泛型,这些假设就只存在于程序员的头脑中(或者如果幸运的话,还存在于代码注释中)。

2.类型约束。

Java程序中的一种流行技术是定义这样的集合,即它的元素或键是公共类型的,比如“String列表”或者“String到String的映射”。

通过在变量声明中捕获这一附加的类型信息,泛型允许编译器实施这些附加的类型约束。

类型错误现在就可以在编译时被捕获了,而不是在运行时当作ClassCastException被抛出来。

将类型检查从运行时挪到编译时有助于您更容易找到错误,并可提高程序的可靠性。

3.消除强制类型转换。

泛型的一个附带好处是,消除源代码中的许多强制类型转换。

这使得代码更加可读,并且减少了出错机会。

7.*.1泛型类与泛型接口1.泛型类在定义带类型参数的类时,在紧跟类命之后的<>内,指定一个或多个类型参数的名字,同时也可以对类型参数的取值范围进行限定,多个类型参数之间用“,”号分隔。

定义完类型参数后,可以在定义位置之后的类的几乎任意地方(静态块,静态属性,静态方法除外)使用类型参数,就像使用普通的类型一样。

我们更改上面的代码,使用泛型类:程序清单:1.public class DemoTest{2.public static void main(String[]args){3.//实例化泛型类4.Position<Integer,Integer>p1=new Position<Integer,Integer>();5.p1.setX(50);6.p1.setY(50);7.int x=p1.getX();8.int y=p1.getY();9.System.out.println("This Position is:"+x+","+y);10.Position<Double,String>p2=new Position<Double,String>();11.p2.setX(37.13);12.p2.setY("东经100度");13.double m=p2.getX();14.String n=p2.getY();15.System.out.println("This Position is:"+m+","+n);16.}17.}18.//定义泛型类19.class Position<T1,T2>{20.T1x;21.T2y;22.//由于篇幅原因,这里省去setter和getter方法,请读者实验室自行加上23.}This Position is:50,50This Position is:37.13,东经100度程序说明:与普通类的定义相比,上面的代码在类名后面多出了<T1,T2>,T1,T2是自定义的标识符,也是参数,用来传递数据的类型,而不是数据的值,我们称之为类型参数。

在泛型中,不但数据的值可以通过参数传递,数据的类型也可以通过参数传递。

T1,T2只是数据类型的占位符,运行时会被替换为真正的数据类型。

类型参数(泛型参数)由尖括号包围,多个参数由英文逗号分隔,如<T>或<T,E>。

类型参数需要在类名后面给出。

一旦给出了类型参数,就可以在类中使用了。

类型参数必须是一个合法的标识符,习惯上使用单个大写字母,通常情况下,K表示键,V表示值,E表示异常或错误,T表示一般意义上的数据类型。

泛型类在实例化时必须指出具体的类型,也就是向类型参数传值,格式为:className variable<dataType1,dataType2>=new className<dataType1,dataType2>();也可以省略等号右边的数据类型,但是会产生警告,即:className variable<dataType1,dataType2>=new className();因为在使用泛型类时指明了数据类型,赋给其他类型的值会抛出异常,既不需要向下转型,也没有潜在的风险,比自动封装和向上转型要更加实用。

注意:1、泛型是Java1.5的新增特性,它以C++模板为参照,本质是参数化类型(Parameterized Type)的应用。

2、类型参数只能用来表示引用类型,不能用来表示基本类型,如int、double、char等。

但是传递基本类型不会报错,因为它们会自动封装成对应的包装类。

2.泛型接口在Java中也可以定义泛型接口,这里不再赘述,仅仅给出示例代码:程序清单:1.public class DemoTest{2.public static void main(String arsg[]){<String>obj=new InfoImp<String>("");4.System.out.println("Length Of String:"+obj.getVar().length());5.}6.}7.//定义泛型接口8.interface Info<T>{9.public T getVar();10.}11.//实现接口12.class InfoImp<T>implements Info<T>{13.private T var;14.//定义泛型构造方法15.public InfoImp(T var){16.this.setVar(var);17.}//由于篇幅原因,省去了setter和getter方法,请读者加上18.}Length Of String:187.*.2泛型方法1.泛型方法的使用除了定义泛型类,还可以定义泛型方法,在定义带类型参数的方法时,在紧跟可见范围修饰(例如public)之后的<>内,指定一个或多个类型参数的名字,同时也可以对类型参数的取值范围进行限定,多个类型参数之间用“,”号分隔。

定义完类型参数后,可以在定义位置之后的方法的任意地方使用类型参数,就像使用普通的类型一样。

例如,定义一个打印坐标的泛型方法。

程序清单:1.public class DemoTest{2.public static void main(String[]args){3.//实例化泛型类4.Position<Integer,Integer>p1=new Position<Integer,Integer>();5.p1.setX(52);6.p1.setY(50);7.p1.printPosition(p1.getX(),p1.getY());8.Position<Double,String>p2=new Position<Double,String>();9.p2.setX(37.13);10.p2.setY("东经100度");11.p2.printPosition(p2.getX(),p2.getY());12.}13.}14.//定义泛型类15.class Position<T1,T2>{16.T1x;17.T2y;//由于篇幅原因,省去了setter和getter方法,请读者加上18.//定义泛型方法19.public<T1,T2>void printPosition(T1x,T2y){20.T1m=x;21.T2n=y;22.System.out.println("This Position is:"+m+","+n);23.}24.}输出结果:This Position is:50,50This Position is:37.13,东经100度程序说明:上面的代码中定义了一个泛型方法printPosition(),既有普通参数,也有类型参数,类型参数需要放在修饰符后面、返回值类型前面。

相关文档
最新文档