基于java中泛型的总结分析

 更新时间:2013年05月03日 19:20:00   作者:  
本篇文章介绍了,在java中泛型的总结分析。需要的朋友参考下

要我直接说出泛型是个what我还真讲不出来,这里先由一道问题引入:

  定义一个坐标点类,要求能保存各种类型的数据,如:整形,浮点型,和字符串类型

既然变量类型起先不确定,那么很容易想到就是用所有类型的父类,也就是Object类来代替

不废话了,用代码来体现

实例1:用Object来实现不确定的数据类型输入

复制代码 代码如下:

//这是定义的坐标点类
class Point {
    private Object x;
    private Object y;

    //用Object来表示不确定的类型
    public Point(Object x, Object y) {
        this.setX(x);
        this.setY(y);
    }
    public void setX(Object x) {
        this.x = x;
    }
    public Object getX() {
        return x;
    }
    public void setY(Object y) {
        this.y = y;
    }
    public Object getY() {
        return y;
    }

}

//测试类
public class Demo {
    public static void main(String[] args) {
        System.out.println("用浮点数表示坐标: ");
        Point p = new Point(12.23,23.21);
        //这里把Object类转为Double类,然后自动拆箱,下面两种一样
        System.out.println("X的坐标 " + (Double)p.getX());
        System.out.println("Y的坐标 " + (Double)p.getY());
        System.out.println();

        System.out.println("用整数表示坐标: ");
        Point p2 = new Point(12, 23);
        System.out.println("X的坐标 " + (Integer)p2.getX());
        System.out.println("Y的坐标 " + (Integer)p2.getY());
        System.out.println();

        System.out.println("用字符串表示坐标: ");
        Point p3 = new Point("北纬29度", "东经113度");
        System.out.println("X的坐标 " + (String)p3.getX());
        System.out.println("Y的坐标 " + (String)p3.getY());
    }
}

这样就可以代入不同类型数据了,但你别忘了,此时的数据还是Object型,也就是所有类型的父类

你必须清醒的明白自己传入的是什么类型,然后将其做向下转型处理才能使用

虽然这样做满足了需求,不过却隐含了一个不安全因素,为什么说是隐含呢?

比如我们用new Point(12.23,"北纬29度")来构造一个Point对象

然后都用(Double)将其向下转型,会产生什么结果?

没错,编译会通过,但是一旦运行则会发生类型转换异常

要避免类转换异常也很简单,把Object声明换成固定类型声明(如:String x,String y)即可,这样编译时就会报错

然后你就可以寻找出错的地方进行修改

不过如此一来,我们就满足不了需求了

为了达到不存在安全隐患和代入各种数据类型的目的,那些牛人们在JDK1.5当中引入了泛型这一概念

我们来看看如何用泛型改写上面的代码

实例2:泛型类

复制代码 代码如下:

class Point<T> {
    //这里用T来表示不确定的类型
    private T x;
    private T y;
    public Point(T x, T y) {
        this.setX(x);
        this.setY(y);
    }
    public T getX() {
        return x;
    }
    public void setX(T x) {
        this.x = x;
    }
    public T getY() {
        return y;
    }
    public void setY(T y) {
        this.y = y;
    }
}

public class Demo {
    public static void main(String[] args) {
        System.out.println("用浮点数表示坐标: ");
        //用泛型改写后,使用数据无需再做向下转型处理
        Point<Double> p = new Point<Double>(12.23,23.21);
        System.out.println("X的坐标 " + p.getX());
        System.out.println("Y的坐标 " + p.getY());
        System.out.println();

        System.out.println("用整数表示坐标: ");
        Point<Integer> p2 = new Point<Integer>(12, 23);
        System.out.println("X的坐标 " + p2.getX());
        System.out.println("Y的坐标 " + p2.getY());
        System.out.println();

        System.out.println("用字符串表示坐标: ");
        Point<String> p3 = new Point<String>("北纬29度", "东经113度");
        System.out.println("X的坐标 " + p3.getX());
        System.out.println("Y的坐标 " + p3.getY());
    }
}

使用泛型过后,可减少安全隐患的存在

如果此时我们刻意传入不一样的数据类型:

Point<Double> p = new Point<Double>("北纬29度",12.22);

那么,在编译时就会报错

虽然定义了泛型,但如果你在构造函数中并未使用泛型机制的话,那么它便会把数据当作Object处理

这样做的目的主要是为了兼容JDK1.4以前的老代码,如

Point p = new Point(22.11,23.21);

最终运行结果是一样的,但在编译时却会提示警告信息

 

实例3:泛型方法

由上面的例子可以看到,一旦在构造方法中明确对象类型,那么整个类中就将使用同一种类型

最典型的例子是运用在集合框架里面,如:ArrayList<Integer> al = new ArrayList<Integer>();

此时,al中操作的所有对象类型便都是Integer了

可是,有时候我们并不希望固定死操作的对象,而是希望更够更加灵活的使用泛型技术

这个时候就可以尝试泛型方法

复制代码 代码如下:

//类名后面不再定义泛型
class Print {
    //在方法中定义泛型
    public <T> void print(T t) {
        System.out.println(t);
    }

    public <E> void show(E e) {
        System.out.println(e);
    }
}

public class Demo {
    public static void main(String[] args) {
        Print p = new Print();
        p.print(12);
        p.print("hello");
        p.show(new Integer(33));
        p.show(23);
    }
}

其实这样一来,与在方法中使用Object对象已经没有什么太大区别了

何况,JDK1.5之后加入了自动拆装箱功能,省去了需要向下转型的麻烦

 

实例4:泛型接口

复制代码 代码如下:

//定义一个泛型接口
interface Inter<T>
{
    public void print(T t);
}

//实现方式一:
class InterDemo1 implements Inter<String> {
    public void print(String t) {
        System.out.println("print: " + t);
    }
}

//实现方式二:
class InterDemo2<T> implements Inter<T> {
    public void print(T t) {
        System.out.println("print: " + t);
    }
}

class Demo {
    public static void main(String[] args) {
        InterDemo1 id1 = new InterDemo1();
        id1.print("hello");
        InterDemo2<Integer> id2 = new InterDemo2<Integer>();
        id2.print(new Integer(23));
    }
}

实现泛型接口的方式有两种,一种是在实现的时候指定泛型类型

另一种是依然使用泛型,在构造的时候确定泛型类型

相关文章

  • 集合框架(Collections Framework)详解及代码示例

    集合框架(Collections Framework)详解及代码示例

    这篇文章主要介绍了集合框架(Collections Framework)详解及代码示例,文章涉及集合数组的区别,collection接口,iterator迭代器,list接口及其用法,LinkedHashSet集合等有关内容,具有一定参考价值,需要的朋友可以了解下。
    2017-11-11
  • javaWeb如何实现随机图片验证码详解

    javaWeb如何实现随机图片验证码详解

    这篇文章主要给大家介绍了关于javaWeb如何实现随机图片验证码的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-03-03
  • java设计模式之观察者模式简单解读

    java设计模式之观察者模式简单解读

    这篇文章主要介绍了java设计模式之观察者模式简单解读,观察者模式是在对象之间定义了一对多的依赖,这样一来,当一个对象改变状态,依赖它的对象会收到通知并自动更新,需要的朋友可以参考下
    2023-10-10
  • 浅谈JAVA 线程状态中可能存在的一些误区

    浅谈JAVA 线程状态中可能存在的一些误区

    这篇文章主要介绍了浅谈JAVA 线程状态中可能存在的一些误区,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-04-04
  • SpringBoot项目中JDK动态代理和CGLIB动态代理的使用详解

    SpringBoot项目中JDK动态代理和CGLIB动态代理的使用详解

    JDK动态代理和CGLIB动态代理都是SpringBoot中实现AOP的重要技术,JDK动态代理通过反射生成代理类,适用于目标类实现了接口的场景,性能较好,易用性高,但必须实现接口且不能代理final方法,CGLIB动态代理通过生成子类实现代理
    2025-03-03
  • 一键打包压缩,Java项目变身JAR

    一键打包压缩,Java项目变身JAR

    想要一键打包Java项目生成JAR文件并进行压缩?本指南将带你轻松驾驭这项看似复杂的任务,让我们一起揭开神秘的面纱,轻松打包,高效出发!
    2023-12-12
  • 详解Spring Cloud负载均衡重要组件Ribbon中重要类的用法

    详解Spring Cloud负载均衡重要组件Ribbon中重要类的用法

    本篇文章主要介绍了详解Spring Cloud负载均衡重要组件Ribbon中重要类的用法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-03-03
  • Netty中的心跳检测机制详解

    Netty中的心跳检测机制详解

    这篇文章主要介绍了Netty中的心跳检测机制详解,Netty 是 基于 TCP 协议开发的,在四层协议 TCP 协议的实现中也提供了 keepalive 报文用来探测对端是否可用,TCP 层将在定时时间到后发送相应的 KeepAlive 探针以确定连接可用性,需要的朋友可以参考下
    2023-12-12
  • jetbrain fleet对标vscode实际操作

    jetbrain fleet对标vscode实际操作

    Gradle是一个基于Apache Ant和Apache Maven概念项目自动化构建开源工具,jetbrain家的fleet(已获得预览权限)直接对标vscode , fleet有望超过vscode吗?今天我们实际操作下
    2021-12-12
  • 详解static 和 final 和 static final区别

    详解static 和 final 和 static final区别

    这篇文章主要介绍了static 和 final 和 static final区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-04-04

最新评论