Java泛型详解,通俗易懂只需5分钟
Java的泛型详解(一)

Java的泛型详解(⼀)Java的泛型详解泛型的好处编写的代码可以被不同类型的对象所重⽤。
因为上⾯的⼀个优点,泛型也可以减少代码的编写。
泛型的使⽤简单泛型类public class Pair<T> {private T first;private T second;public Pair() {first = null;second = null;}public Pair(T first, T second){this.first = first;this.second = second;}public T getFirst(){return first;}public T getSecond(){return second;}public void setFirst(T first) {this.first = first;}public void setSecond(T second) {this.second = second;}}上⾯例⼦可以看出泛型变量为T;⽤尖括号(<>)括起来,并放在类名后⾯;泛型还可以定义多个类型变量⽐如上⾯的例⼦ first和second不同的类型:public class Pair<T, U> {....}注: 类型变量的定义需要⼀定的规范:(1) 类型变量使⽤⼤写形式,并且要⽐较短;(2)常见的类型变量特别代表⼀些意义:变量E 表⽰集合类型,K和V表⽰关键字和值的类型;T、U、S表⽰任意类型;类定义的类型变量可以作为⽅法的返回类型或者局部变量的类型;例如: private T first;⽤具体的类型替换类型变量就可以实例化泛型类型;例如: Pair<String> 代表将上述所有的T 都替换成了String由此可见泛型类是可以看作普通类的⼯⼚泛型⽅法我们应该如何定义⼀个泛型⽅法呢?泛型的⽅法可以定义在泛型类,也可以定义在普通类,那如果定义在普通类需要有⼀个尖括号加类型来指定这个泛型⽅法具体的类型;public class TestUtils {public static <T> T getMiddle(T... a){return a[a.length / 2];}}类型变量放在修饰符(static)和返回类型的中间;当你调⽤上⾯的⽅法的时候只需要在⽅法名前⾯的尖括号放⼊具体的类型即可;String middle = TestUtils.<String>getMiddle("a", "b", "c");如果上图这种情况其实可以省略,因为编译器能够推断出调⽤的⽅法⼀定是String,所以下⾯这种调⽤也是可以的;String middle = TestUtils.getMiddle("a", "b", "c");但是如果是以下调⽤可能会有问题:如图:可以看到变意思没有办法确定这⾥的类型,因为此时我们⼊参传递了⼀个Double3.14 两个Integer1729 和0 编译器认为这三个不属于同⼀个类型;此时有⼀种解决办法就是把整型写成Double类型类型变量的限定有时候我们不能⽆限制的让使⽤者传递任意的类型,我们需要对我们泛型的⽅法进⾏限定传递变量,⽐如如下例⼦计算数组中最下的元素这个时候是⽆法编译通过的,且编译器会报错因为我们的编译器不能确定你这个T 类型是否有compareTo这个函数,所以这么能让编译器相信我们这个T是⼀定会有compareTo呢?我们可以这么写<T extends Comparable> 这⾥的意思是T⼀定是继承Comparable的类因为Comparable是⼀定有compareTo这个⽅法,所以T⼀定有compareTo⽅法,于是编译器就不会报错了因为加了限定那么min这个⽅法也只有继承了Comparable的类才可以调⽤;如果要限定⽅法的泛型继承多个类可以加extends 关键字并⽤&分割如:T extends Comparable & Serializable限定类型是⽤&分割的,逗号来分割多个类型变量<T extends Comparable & Serializable , U extends Comparable>类型擦除不论什么时候定义⼀个泛型类型,虚拟机都会提供⼀个相应的原始类型(raw type)。
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 泛型详解与范例⽬录⼀、泛型的使⽤⼆、泛型类的定义-类型边界三、类型擦除四、泛型类的使⽤-通配符五、泛型⽅法六、泛型的限制⼀、泛型的使⽤前⾯我们学集合的时候,简单的说过泛型的使⽤。
如下:1ArrayList<Integer> list = new ArrayList<>();那么使⽤是这样的简单,该注意什么?尖括号⾥的类型,只能写引⽤类型基础数据类型的话,就需要写相应的包装类型泛型只是编译时期的⼀种机制,在运⾏时是没有泛型的概念的。
⼆、泛型类的定义-类型边界泛型还有⼀个点就是:泛型的上界。
(类型形参 extends 类型边界)有如下代码:1234public class Algorithm<T extends Comparable<T>> { public T findMax(T[] array) { }}以上代码中,⽅法的作⽤就是传递⼀个数组进去,要求返回这个数组中的最⼤值。
这个时候问题就来了,泛型是T 类型,当调⽤这个⽅法的时候,传递过去的参数类型不⼀定就是简单数据类型啊。
那么这个时候该怎么进⾏判断⼤⼩呢此时这样的泛型写法的作⽤就是:T extends Comparable, 就叫做泛型的上界,当传递参数类型的时候,必须传递过去的参数类型必须是实现了Comparable 接⼝的类型才可以。
换句话说,传递过去的类型必须是可以进⾏⽐较的。
当我们⾃⼰定义的⼀个类Node ,然后实现Comparable 接⼝,就能调⽤如上的⽅法。
切记,这样写的泛型,传递过去的参数类型,必须是实现了Comparable 接⼝的,当然也可以传递Comparable 接⼝本⾝。
三、类型擦除类型擦除值得是:代码编译后,会将泛型T ,全部擦除为Object 类型。
如下代码:上⾯这⼀⾏代码,虽然此时写的是Integer 类型的,但是在编译之后,JVM 会⾃动地将Integer 擦除为Object 。
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的泛型讲解

Java的泛型讲解本文由广州Java培训为你整理:今儿为大家讲解的是JDK5.0支持的新功能Java的泛型。
,JDK1.5 令我们期待很久,可是当他发布的时候却更换版本号为5.0.这说明Java已经有大幅度的变化。
1、Java泛型其实Java的泛型就是创建一个用类型作为参数的类。
就象我们写类的方法一样,方法是这样的method(String str1,String str2 ),方法中参数str1、str2的值是可变的。
而泛型也是一样的,这样写class Java_Generics,这里边的K和V就象方法中的参数str1和str2,也是可变。
1.1.泛型通配符下面我们先看看这些程序://Code list 2void TestGen0Medthod1(List l){for (Object o : l)System.out.println(o);}看看这个方法有没有异议,这个方法会通过编译的,假如你传入String,就是这样List.接着我们调用它,问题就出现了,我们将一个List当作List传给了方法,JVM会给我们一个警告,说这个破坏了类型安全,因为从List中返回的都是Object类型的。
1.2.编写泛型类要注意:1)在定义一个泛型类的时候,在"<>"之间定义形式类型参数,例如:"class TestGen",其中"K", "V"不代表值,而是表示类型。
2)实例化泛型对象的时候,一定要在类名后面指定类型参数的值(类型),一共要有两次书写。
例如:TestGent=new TestGen();3)泛型中,extends并不代表继承,它是类型范围限制。
2、泛型与数据类型转换2.1.消除类型转换在JDK5.0中我们完全可以这么做,这里我们使用泛化版本的HashMap,这样就不用我们来编写类型转换的代码了,类型转换的过程交给编译器来处理,是不是很方便,而且很安全。
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.特性泛型只在编译阶段有效。
Java泛型机制详解

Java泛型机制详解带着问题阅读1、什么是Java泛型,有什么⽤处2、Java泛型的实现机制是什么3、Java泛型有哪些局限和限制Java泛型介绍引⼊泛型之前,试想编写⼀个加法器,为处理不同数字类型,就需要对不同类型参数进⾏重载,但其实现内容是完全⼀样的,如果是⼀个更复杂的⽅法,⽆疑会造成重复。
public int add(int a, int b) {return a + b;}public float add(float a, float b) {return a + b;}public double add(double a, double b) {return a + b;}⼀般的类和⽅法,只能使⽤具体的类型,要么是基本类型,要么是⾃定义的类。
如果要编写可以应⽤于多种类型的代码,这种刻板的限制对代码的束缚就会很⼤。
《Java编程思想》Java在1.5版本引⼊泛型,通过泛型实现的加法代码可简化为:public <T extends Number> double add(T a, T b) {return a.doubleValue() + b.doubleValue();}泛型的核⼼概念是参数化类型,使⽤参数指定⽅法类型,⽽⾮硬编码。
泛型的出现带给我们很多好处,其中最重要的莫过于对集合类的改进,避免了任意类型都可以丢到同⼀个集合⾥的不可靠问题。
然⽽Python和Go的集合可以容纳任意类型,这究竟是进步还是退步呢Java泛型使⽤简介泛型⼀般有三种使⽤⽅式:泛型类、泛型接⼝和泛型⽅法。
泛型类public class GenericClass<T> {private T member;}...// 初始化时指定泛型类型GenericClass<String> instance = new GenericClass<String>();泛型接⼝public interface GenericInterface<T> {void test(T param);}// 实现类指定泛型类型public class GenericClass implements GenericInterface<String> {@Overridepublic void test(String param) {...}}泛型⽅法如前⽂中加法代码的实现就是泛型⽅法。
java 泛型详解

JAVA 协变性逆变性在面向对象的计算机程序语言中,经常涉及到类型之间的转换,例如从具体类小猫到动物之间的类型转换(上行转换),或者从形状向三角形之间的转换(下行转换)。
我们之前往往都比较关注类型本身,却常常忽略类型转换的性质。
最近在拜读《thinking in java》看到一些关于类型转换性质的比较抽象理论的内容,仔细研究一下,分享给大家。
我们将围绕如下三个核心名词:协变性(covariance)、逆变性(contravariance)和无关性(invariant)。
他们都是用来描述类型转换的性质的术语,形式化的描述如下:如果A和B是类型,f表示类型转换,≤表示子类型关系,(例如A≤B,表示A是B 的子类)那么:如果A≤B 则f(A) ≤ f(B) 那么 f是协变的如果A≤B 则f(B) ≤ f(A) 那么 f 是逆变的如果上面两种都不成立,那么f是无关的例如java中,f(A) = List<A> ,这里List声明如下:class List<T>{…}我们可以理解泛型类List输入一个类型参数T,然后将T转换成类型List<T>,这个过程本身是一个类型转换f。
我们举例A = Object,B=String,经过类型变换f以后f(A)=List<Object>,f(B) =List<String>。
String ≤ Object 但是 f(A) ≤ f(b)却不成立。
所以上面的类型转换是无关的。
在Java语言中,有一些语法可以用协变性和逆变性来理解。
数组例如 A = String, B = Object 我们这里有A≤Bf(A) = String[], f(B) = Object[]. 因为Object[] objects = new String[n]. 所以我们可以认为数组具有协变性。
X = Y1. 协变返回值在面向对象语言中,一个协变返回值方法是一个在子类覆盖该方法的时候,方法的返回值可以被一个“更窄”的类型所替代。