全面总结Java泛型

终结者T800
• 阅读 102

虽然Scala创始人Martin Odersky说当年正是因为Java泛型的丑陋,所以才想到要创建一个新的语言,不过这仍然不妨碍我们学习Java泛型。毕竟即使听说Java泛型不好用,但好不好用还是得会用了才知道。下面是一些有关Java泛型的总结:

普通泛型

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("it") ;                // 设置字符串
            System.out.println(p.getVar().length()) ;        // 取得字符串的长度
    }

};

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为Integer
            t.setKey("汤姆") ;                // 设置第一个内容
            t.setValue(20) ;                        // 设置第二个内容
            System.out.print("姓名;" + t.getKey()) ;                // 取得信息
            System.out.print(",年龄;" + t.getValue()) ;                // 取得信息

    }

};
通配符

class Info<T>{

    private T var ;                // 定义泛型变量
    public void setVar(T var){
            this.var = var ;
    }
    public T getVar(){
            return this.var ;
    }
    public String toString(){        // 直接打印
            return this.var.toString() ;
    }

};
public class GenericsDemo14{

    public static void main(String args[]){
            Info<String> i = new Info<String>() ;                // 使用String为泛型类型
            i.setVar("it") ;                                                        // 设置内容
            fun(i) ;
    }
    public static void fun(Info<?> temp){                // 可以接收任意的泛型对象
            System.out.println("内容:" + temp) ;
    }

};
受限泛型

class Info<T>{

    private T var ;                // 定义泛型变量
    public void setVar(T var){
            this.var = var ;
    }
    public T getVar(){
            return this.var ;
    }
    public String toString(){        // 直接打印
            return this.var.toString() ;
    }

};
public class GenericsDemo17{

    public static void main(String args[]){
            Info<Integer> i1 = new Info<Integer>() ;                // 声明Integer的泛型对象
            Info<Float> i2 = new Info<Float>() ;                        // 声明Float的泛型对象
            i1.setVar(30) ;                                                                        // 设置整数,自动装箱
            i2.setVar(30.1f) ;                                                                // 设置小数,自动装箱
            fun(i1) ;
            fun(i2) ;
    }
    public static void fun(Info<? extends Number> temp){        // 只能接收Number及其Number的子类
            System.out.print(temp + "、") ;
    }

};

class Info<T>{

    private T var ;                // 定义泛型变量
    public void setVar(T var){
            this.var = var ;
    }
    public T getVar(){
            return this.var ;
    }
    public String toString(){        // 直接打印
            return this.var.toString() ;
    }

};
public class GenericsDemo21{

    public static void main(String args[]){
            Info<String> i1 = new Info<String>() ;                // 声明String的泛型对象
            Info<Object> i2 = new Info<Object>() ;                // 声明Object的泛型对象
            i1.setVar("hello") ;
            i2.setVar(new Object()) ;
            fun(i1) ;
            fun(i2) ;
    }
    public static void fun(Info<? super String> temp){        // 只能接收String或Object类型的泛型
            System.out.print(temp + "、") ;
    }

};
泛型无法向上转型

class Info<T>{

    private T var ;                // 定义泛型变量
    public void setVar(T var){
            this.var = var ;
    }
    public T getVar(){
            return this.var ;
    }
    public String toString(){        // 直接打印
            return this.var.toString() ;
    }

};
public class GenericsDemo23{

    public static void main(String args[]){
            Info<String> i1 = new Info<String>() ;                // 泛型类型为String
            Info<Object> i2 = null ;
            i2 = i1 ;                                                                //这句会出错 incompatible types
    }

};
泛型接口

interface Info<T>{ // 在接口上定义泛型

    public T getVar() ;        // 定义抽象方法,抽象方法的返回值就是泛型类型

}
class InfoImpl<T> implements Info<T>{ // 定义泛型接口的子类

    private T var ;                                // 定义属性
    public InfoImpl(T var){                // 通过构造方法设置属性内容
            this.setVar(var) ;        
    }
    public void setVar(T var){
            this.var = var ;
    }
    public T getVar(){
            return this.var ;
    }

};
public class GenericsDemo24{

    public static void main(String arsg[]){
            Info<String> i = null;                // 声明接口对象
            i = new InfoImpl<String>("汤姆") ;        // 通过子类实例化对象
            System.out.println("内容:" + i.getVar()) ;
    }

};

interface Info<T>{ // 在接口上定义泛型

    public T getVar() ;        // 定义抽象方法,抽象方法的返回值就是泛型类型

}
class InfoImpl implements Info<String>{ // 定义泛型接口的子类

    private String var ;                                // 定义属性
    public InfoImpl(String var){                // 通过构造方法设置属性内容
            this.setVar(var) ;        
    }
    public void setVar(String var){
            this.var = var ;
    }
    public String getVar(){
            return this.var ;
    }

};
public class GenericsDemo25{

    public static void main(String arsg[]){
            Info i = null;                // 声明接口对象
            i = new InfoImpl("汤姆") ;        // 通过子类实例化对象
            System.out.println("内容:" + i.getVar()) ;
    }

};
泛型方法

class Demo{

    public <T> T fun(T t){                        // 可以接收任意类型的数据
            return t ;                                        // 直接把参数返回
    }

};
public class GenericsDemo26{

    public static void main(String args[]){
            Demo d = new Demo()        ;        // 实例化Demo对象
            String str = d.fun("汤姆") ; //        传递字符串
            int i = d.fun(30) ;                // 传递数字,自动装箱
            System.out.println(str) ;        // 输出内容
            System.out.println(i) ;                // 输出内容
    }

};
通过泛型方法返回泛型类型实例

class Info<T extends Number>{ // 指定上限,只能是数字类型

    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 GenericsDemo27{

    public static void main(String args[]){
            Info<Integer> i = fun(30) ;
            System.out.println(i.getVar()) ;
    }
    public static <T extends Number> Info<T> fun(T param){//方法中传入或返回的泛型类型由调用方法时所设置的参数类型决定
            Info<T> temp = new Info<T>() ;                // 根据传入的数据类型实例化Info
            temp.setVar(param) ;                // 将传递的内容设置到Info对象的var属性之中
            return temp ;        // 返回实例化对象
    }

};
使用泛型统一传入的参数类型

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 GenericsDemo28{

    public static void main(String args[]){
            Info<String> i1 = new Info<String>() ;
            Info<String> i2 = new Info<String>() ;
            i1.setVar("HELLO") ;                // 设置内容
            i2.setVar("汤姆") ;                // 设置内容
            add(i1,i2) ;
    }
    public static <T> void add(Info<T> i1,Info<T> i2){
            System.out.println(i1.getVar() + " " + i2.getVar()) ;
    }

};
泛型数组

public class GenericsDemo30{

    public static void main(String args[]){
            Integer i[] = fun1(1,2,3,4,5,6) ;        // 返回泛型数组
            fun2(i) ;
    }
    public static <T> T[] fun1(T...arg){        // 接收可变参数
            return arg ;                        // 返回泛型数组
    }
    public static <T> void fun2(T param[]){        // 输出
            System.out.print("接收泛型数组:") ;
            for(T t:param){
                    System.out.print(t + "、") ;
            }
    }

};
泛型的嵌套设置

class Info<T,V>{ // 接收两个泛型类型

    private T var ;
    private V value ;
    public Info(T var,V value){
            this.setVar(var) ;
            this.setValue(value) ;
    }
    public void setVar(T var){
            this.var = var ;
    }
    public void setValue(V value){
            this.value = value ;
    }
    public T getVar(){
            return this.var ;
    }
    public V getValue(){
            return this.value ;
    }

};
class Demo<S>{

    private S info ;
    public Demo(S info){
            this.setInfo(info) ;
    }
    public void setInfo(S info){
            this.info = info ;
    }
    public S getInfo(){
            return this.info ;
    }

};
public class GenericsDemo31{

    public static void main(String args[]){
            Demo<Info<String,Integer>> d = null ;                // 将Info作为Demo的泛型类型
            Info<String,Integer> i = null ;        // Info指定两个泛型类型
            i = new Info<String,Integer>("汤姆",30) ;         // 实例化Info对象
            d = new Demo<Info<String,Integer>>(i) ;        // 在Demo类中设置Info类的对象
            System.out.println("内容一:" + d.getInfo().getVar()) ;
            System.out.println("内容二:" + d.getInfo().getValue()) ;
    }

};

点赞
收藏
评论区
推荐文章
Wesley13 Wesley13
4年前
java 泛型详解
对java的泛型特性的了解仅限于表面的浅浅一层,直到在学习设计模式时发现有不了解的用法,才想起详细的记录一下。本文参考java泛型详解、Java中的泛型方法、java泛型详解1\.概述泛型在java中有很重要的地位,在面向对象编程及各种设计模式中有非常广泛的应用。什么是泛型?为什么要使用泛型?泛型,即“参数化类型”。一提到参数,最熟
Wesley13 Wesley13
4年前
java泛型
一、实现机制java泛型实现方法为类型擦除,基于这种方法实现的泛型称为伪泛型。java泛型只在源代码中存在,在编译后的文件中替换为原生类型,并插入强制转换。(真正的泛型是应该存在于源码、编译后文件、运行期)二、擦除实例源码:List<StringtestListnewArrayList<String();
浪人 浪人
4年前
死磕Java泛型(一篇就够)
Java泛型,算是一个比较容易产生误解的知识点,因为Java的泛型基于擦除实现,在使用Java泛型时,往往会受到泛型实现机制的限制,如果不能深入全面的掌握泛型知识,就不能较好的驾驭使用泛型,同时在阅读开源项目时也会处处碰壁,这一篇就带大家全面深入的死磕Java泛型。泛型擦除初探相信泛型大家都使用过,所以一些基础的知识点就不废话了,以免显得啰嗦。
浪人 浪人
4年前
java 泛型详解-绝对是对泛型方法讲解最详细的,没有之一
java泛型详解绝对是对泛型方法讲解最详细的,没有之一对java的泛型特性的了解仅限于表面的浅浅一层,直到在学习设计模式时发现有不了解的用法,才想起详细的记录一下。本文参考、、1、概述泛型在java中有很重要的地位,在面向对象编程及各种设计模式中有非常广泛的应用。什么是泛型?
Stella981 Stella981
4年前
Gson通过借助TypeToken获取泛型参数的类型的方法
最近在使用Google的Gson包进行Json和Java对象之间的转化,对于包含泛型的类的序列化和反序列化Gson也提供了很好的支持,感觉有点意思,就花时间研究了一下。由于Java泛型的实现机制,使用了泛型的代码在运行期间相关的泛型参数的类型会被擦除,我们无法在运行期间获知泛型参数的具体类型(所有的泛型类型在运行时都是Object类型)。但是有的时候
Wesley13 Wesley13
4年前
Java泛型详解
引言Java泛型是jdk1.5中引入的一个新特性,泛型提供了编译时的类型检测机制,该机制允许程序员在编译时检测到非法的类型。泛型是Java中一个非常重要的知识点,在Java集合类框架中泛型被广泛应用。本文我们将从零开始来看一下Java泛型的设计,将会涉及到通配符处理,以及让人苦恼的类型擦除。泛型基础
Wesley13 Wesley13
4年前
Java的泛型详解(一)
Java的泛型详解(一)编写的代码可以被不同类型的对象所重用。因为上面的一个优点,泛型也可以减少代码的编写。1|2泛型的使用简单泛型类publicclassPair{privateTfirst;privateTsecond;publicPair(){firstnull;secondnull;
Stella981 Stella981
4年前
20175209 《Java程序设计》第八周学习总结
20175209《Java程序设计》第八周学习总结一、教材知识点总结1.泛型1.泛型类声明:格式classPeople<EPeople是泛型类名称E是泛型列表,可以是任何对象或接口,但不能是基本类型数据
Wesley13 Wesley13
4年前
JAVA泛型的简单思考一
对于熟悉JAVA语言的coder来说,泛型绝对曾让自己伤透脑筋,因为java中的泛型就像是一个糖果,但嚼起来却痛苦不堪(可能有点过分,不过看很多论坛贴吧的抱怨,我觉得也是不可否认的)。每个初涉泛型的人可能都会经历这样的阶段,什么是泛型,为什么会有泛型,怎么样使用泛型,它能给我们带来什么?等等   其实早在JDK1.5之前,java还不存在泛型,但j
Wesley13 Wesley13
4年前
JAVA 泛型中的通配符 T,E,K,V 傻傻分不清楚 ?
前言Java泛型(generics)是JDK5中引入的一个新特性,泛型提供了编译时类型安全检测机制,该机制允许开发者在编译时检测到非法的类型。泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。泛型带来的好处在没有泛型的情况的下,通过对类型Object的引用来实现参数的“任意化”,“任意化”带
可莉 可莉
4年前
20175209 《Java程序设计》第八周学习总结
20175209《Java程序设计》第八周学习总结一、教材知识点总结1.泛型1.泛型类声明:格式classPeople<EPeople是泛型类名称E是泛型列表,可以是任何对象或接口,但不能是基本类型数据