基于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));
    }
}

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

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

(0)

相关推荐

  • 多个java泛型示例分享

    1.泛型类 1.1普通泛型 复制代码 代码如下: package test.lujianing;/** * 泛型类 * @param <T> */class Test<T>{    private T obj;    public void setValue(T obj){        this.obj =obj;    }    public T getValue(){        System.out.println(obj.getClass().getName());  

  • Java中的泛型详解

    所谓泛型:就是允许在定义类.接口指定类型形参,这个类型形参在将在声明变量.创建对象时确定(即传入实际的类型参数,也可称为类型实参) 泛型类或接口 "菱形"语法 复制代码 代码如下: //定义   public interface List<E> extends Collection<E>    public class HashMap<K,V> extends AbstractMap<K,V>  implements Map<K,V

  • java泛型学习示例

    Java泛型(Generics)是JDK5开始引入的一个新特性,允许在定义类和接口的时候使用类型参数(Type Parameter).声明的类型参数在使用时用具体的类型来替换,现在泛型最主要的应用是在JDK5中的新集合类框架中,Map, List均有用到.其中的优点不言而喻,我们可以横向扩展更多的类,缺点呢,其实也就是他的优点,因为这需要我们在使用泛型类的时候,要很清楚自己的代码目地,不能使用错误的类型. 最基本的泛型类 复制代码 代码如下: package com.garinzhang.jav

  • java 泛型的详解及实例

    java 泛型的详解及实例 Java在1.5版本中增加了泛型,在没有泛型之前,从集合中读取每一个对象都需要进行强转,如果一不小心插入了类型错误的对象,在运行时就会报错,给日常开发带来了很多不必要的麻烦,比如以下代码: public class TestGeneric { public static void main(String[] args) { List list = new ArrayList(); list.add(" name:"); list.add(" zer

  • Java编程思想里的泛型实现一个堆栈类 分享

    觉得作者写得太好了,不得不收藏一下. 对这个例子的理解: //类型参数不能用基本类型,T和U其实是同一类型. //每次放新数据都成为新的top,把原来的top往下压一级,通过指针建立链接. //末端哨兵既是默认构造器创建出的符合end()返回true的节点. 复制代码 代码如下: //: generics/LinkedStack.java// A stack implemented with an internal linked structure.package generics; publi

  • 解析Java的Jackson库中对象的序列化与数据泛型绑定

    Jackson对象序列化 这里将介绍将Java对象序列化到一个JSON文件,然后再读取JSON文件获取转换为对象.在这个例子中,创建了Student类.创建将有学生对象以JSON表示在一个student.json文件. 创建一个名为JacksonTester在Java类文件在 C:\>Jackson_WORKSPACE. 文件: JacksonTester.java import java.io.File; import java.io.IOException; import org.codeh

  • Java8中对泛型目标类型推断方法的改进

    一.简单理解泛型 泛型是Java SE 1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数.通俗点将就是"类型的变量".这种类型变量可以用在类.接口和方法的创建中. 理解Java泛型最简单的方法是把它看成一种便捷语法,能节省你某些Java类型转换(casting)上的操作: 复制代码 代码如下: List<Apple> box = new ArrayList<Apple>();box.add(new Apple());Apple a

  • 基于java中泛型的总结分析

    要我直接说出泛型是个what我还真讲不出来,这里先由一道问题引入: 定义一个坐标点类,要求能保存各种类型的数据,如:整形,浮点型,和字符串类型 既然变量类型起先不确定,那么很容易想到就是用所有类型的父类,也就是Object类来代替 不废话了,用代码来体现 实例1:用Object来实现不确定的数据类型输入 复制代码 代码如下: //这是定义的坐标点类class Point {    private Object x;    private Object y; //用Object来表示不确定的类型 

  • 基于java中反射的总结分析

    刚开始学习java的时候真的很难理解反射到底是个什么东西 一些书籍,哪怕是很经典的书籍都解释的让人感觉懵懵的,或许的确是我太笨 况且,网上说在将来学习框架的时候需要经常应用到反射机制,这样一来总让人心里有些不安 就方才偶然又把讲解反射的章节和视频看了一点,觉得能理解一些了 现在决定一鼓作气,边看边写,顺便把一些主要的内容和操作都记载到这里 我想,对于我这么一个笨笨的人来说,学习的最好方法也许就是不断重复 遇到不懂的知识就停下来把以往的重新学一遍,虽然浪费了很多时间,但对我也有些效果 我的理解是:

  • 基于Java中的数值和集合详解

    数组array和集合的区别: (1) 数值是大小固定的,同一数组只能存放一样的数据. (2) java集合可以存放不固定的一组数据 (3) 若程序事不知道究竟需要多少对象,需要在空间不足时自动扩增容量,则需要使用容器类库,array不适用 数组转换为集合: Arrays.asList(数组) 示例: int[] arr = {1,3,4,6,6}; Arrays.asList(arr); for(int i=0;i<arr.length;i++){ System.out.println(arr[

  • java中继承测试代码分析

    继承:可以基于已经存在的类构造一个新类.继承已经存在的类就可以复用这些类的方法和域.在此基础上,可以添加新的方法和域,从而扩充了类的功能. public class ExtendsStu { /*动物类:动物都可以动 * 1.Dog 2.Cat * 在java中,子类可以继承父类的属性和功能; * 继承关系的指定: 子类 extends 父类 * 不能被继承的资源: * 1.子类不能继承父类的构造方法,而且必须调用一个父类的构造器(因为生成子类对象的时候会初始化父类属性) * 2.私有的资源不能

  • 基于Java 生产者消费者模式(详细分析)

    生产者消费者模式是多线程中最为常见的模式:生产者线程(一个或多个)生成面包放进篮子里(集合或数组),同时,消费者线程(一个或多个)从篮子里(集合或数组)取出面包消耗.虽然它们任务不同,但处理的资源是相同的,这体现的是一种线程间通信方式. 本文将先说明单生产者单消费者的情况,之后再说明多生产者多消费者模式的情况.还会分别使用wait()/nofity()/nofityAll()机制.lock()/unlock()机制实现这两种模式. 在开始介绍模式之前,先解释下wait().notify()和no

  • 基于Java中UDP的广播形式(实例讲解)

    UDP---用户数据报协议,是一个简单的面向数据报的运输层协议.UDP不提供可靠性,它只是把应用程序传给IP层的数据报发送出去,但是并不能保证它们能到达目的地 ,也不能保证数据包到达的顺序.由于UDP在传输数据报前不用在客户和服务器之间建立一个连接,且没有超时重发等机制,故而传输速度很快. 在Java中UDP的实现: * UDP: * 客户端: * 1.创建用于UDP通信的socket对象---DatagramSocket(用于UDP数据的发送和接收)---数据报套接字 * 2.准备数据,封装包

  • java中TESTful架构原理分析

    目录 1. 什么是REST 2. 理解RESTful 2. 1 资源与URI 2. 2 统一资源接口 GET POST PUT DELETE 2. 3 资源的表述 在URI里边带上版本号 使用URI后缀来区分表述格式 如何处理不支持的表述格式 2. 4 资源的链接 2. 5 状态的转移 2. 5.1 应用状态与资源状态 2. 5.2 应用状态的转移 3. 总结 1. 什么是REST REST全称是Representational State Transfer,中文意思是表述(编者注:通常译为表征

  • Java中注解与原理分析详解

    目录 一.注解基础 二.注解原理 三.常用注解 1.JDK注解 2.Lombok注解 四.自定义注解 1.同步控制 2.类型引擎 一.注解基础 注解即标注与解析,在Java的代码工程中,注解的使用几乎是无处不在,甚至多到被忽视: 无论是在JDK源码或者框架组件,都在使用注解能力完成各种识别和解析动作:在对系统功能封装时,也会依赖注解能力简化各种逻辑的重复实现: 基础接口 在Annotation的源码注释中有说明:所有的注解类型都需要继承该公共接口,本质上看注解是接口,但是代码并没有显式声明继承关

  • Java中泛型的示例详解

    目录 泛型概述 使用泛型的好处 泛型的定义与使用 定义和使用含有泛型的类 含有泛型的方法 含有泛型的接口 泛型通配符 通配符基本使用 通配符高级使用----受限泛型 泛型概述 我们都知道集合中是可以存放任意对象的,只要把对象存储集合后,那么这时他们都会被提升成Object类型.当我们在取出每一个对象,并且进行相应的操作,这时必须采用类型转换. 大家观察下面代码: public class GenericDemo { public static void main(String[] args) {

  • 基于Java中的StringTokenizer类详解(推荐)

    StringTokenizer是字符串分隔解析类型,属于:Java.util包. 1.StringTokenizer的构造函数 StringTokenizer(String str):构造一个用来解析str的StringTokenizer对象.java默认的分隔符是"空格"."制表符('\t')"."换行符('\n')"."回车符('\r')". StringTokenizer(String str,String delim)

随机推荐