泛型入门

为什么使用泛型

  要求设计出一个可以表示坐标点的类,坐标由X和Y组成。

  坐标表示方法:

  整数:x=10,Y=20;

  小数:X=10.5,Y=20.6

  字符串:X="东经180度",Y=“北纬30度”

  问,此类怎么设计。

 题目分析

  肯定要设计表示坐标点的类。类名称:Point。

  但是坐标的X,Y保存的数据类型有三种(int,float,String),要想使用一个类可以同时接收这三种类型,则现在只能使用Object类,因为Object可以接受任何类型的

数据,都会自动发生向上转型。这样三种数据类型会发生以下转变: 

数字(int)->自动装箱成(Integer)->向上转型Object接收
小数点(float)->自动装箱成(Float)->向上转型Object接收
字符串(String)->向上转型Object接收

  Point类:

class Point{
    private Object x ;        // 表示X坐标
    private Object y ;        // 表示Y坐标
    public void setX(Object x){
        this.x = x ;
    }
    public void setY(Object y){
        this.y = y ;
    }
    public Object getX(){
        return this.x ;
    }
    public Object getY(){
        return this.y ;
    }
};

  总体代码如下:需要注意向上转型和向下转型的自动装箱和自动拆箱操作。

class Point{
    private Object x ;        // 表示X坐标
    private Object y ;        // 表示Y坐标
    public void setX(Object x){
        this.x = x ;
    }
    public void setY(Object y){
        this.y = y ;
    }
    public Object getX(){
        return this.x ;
    }
    public Object getY(){
        return this.y ;
    }
};

public class GenericsDemo01{
    public static void main(String args[]){
        Point p = new Point() ;    // 声明一个Point的对象
        p.setX(10) ;        // 利用自动装箱操作:int --> Integer --> Object
        p.setY(20) ;        // 利用自动装箱操作:int --> Integer --> Object
        int x = (Integer)p.getX() ;    // 取出数据先变为Integer,之后自动拆箱,Integer-->int
        int y = (Integer)p.getY() ;    // 取出数据先变为Integer,之后自动拆箱
        System.out.println("整数表示,X坐标为:" + x) ;
        System.out.println("整数表示,Y坐标为:" + y) ;
    }
};

  以上代码存在很大问题,加设里面的数据类型变换一下,则则自动拆箱操作处就要修改强制转型代码。

认识泛型

  是在类声明的时候,通过一个标识表示类中某个属性的类型或者是某个方法的返回值及参数类型。这样在类声明和实例化的时候只要指定好要使用的类型即可。

  泛型定义实例:

class Point<T>{        // 此处可以随便写标识符号,T是type的简称
    private T var ;    // var的类型由T指定,即:由外部指定
    public T getVar(){    // 返回值的类型由外部决定
        return var ;
    }
    public void setVar(T var){    // 设置的类型也由外部决定
        this.var = var ;
    }
};

  结合上面完整的一个例子:

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

  可以更好的保护数据类型。

  通过泛型就可以直接修改之前的程序。

  修改结果如下:

class Point<T>{
    private T x ;        // 表示X坐标
    private T y ;        // 表示Y坐标
    public void setX(T x){
        this.x = x ;
    }
    public void setY(T y){
        this.y = y ;
    }
    public T getX(){
        return this.x ;
    }
    public T getY(){
        return this.y ;
    }
};

public class GenericsPoint{
    public static void main(String args[]){
        Point<Integer> p = new Point<Integer>() ;
        p.setX(10) ;        // 利用自动装箱操作:int --> Integer
        p.setY("北纬210度") ;        // 利用自动装箱操作:int --> Integer
        int x = p.getX() ;    // 自动拆箱
        int y = p.getY() ;    // 自动拆箱
        System.out.println("整数表示,X坐标为:" + x) ;
        System.out.println("整数表示,Y坐标为:" + y) ;
    }
};

  在这样的程序中,减少了类型转换的操作(不用用一个Object类在类中定义,不用向上转型,向下转型,拆箱,装箱)。

构造方法中使用泛型

  泛型也可以在构造方法中使用,一般有可能为构造方法为类中属性赋值。

  为构造方法属性赋值实例:

class Point<T>{        // 此处可以随便写标识符号,T是type的简称
    private T var ;    // var的类型由T指定,即:由外部指定
    public Point(T var){        // 通过构造方法设置内容
        this.var = var ;
    }
    public T getVar(){    // 返回值的类型由外部决定
        return var ;
    }
    public void setVar(T var){    // 设置的类型也由外部决定
        this.var = var ;
    }
};
public class GenericsDemo08{
    public static void main(String args[]){
        Point<String> p = new Point<String>("MLDN") ;    // 里面的var类型为String类型
        System.out.println("内容:" + p.getVar()) ;
    }
};

指定两个泛型类型,如下:

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

    }
};

泛型的安全警告

  在泛型应用中最好在声明类对象的时候指定其内部的数据类型。例如:“Info<String>”,但是也可不指定类型。

package Thread1;
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 demo1{
    public static void main(String args[]){
        Info i = new Info() ;        // 警告,没有指定泛型类型
        i.setVar("MLDN") ;            // 设置字符串
        System.out.println("内容:" + i.getVar()) ;
    }
};

  运行结果:

内容:MLDN

  程序不会影响执行,但是在Info类中并没有指定泛型类型,则在java中为了保证程序依然可以运行,会将T自动设置成Object类型。这样一来就可以接受任意数据类型。

也就是说,此时的var类型就是Object,所有的泛型信息将被擦除。

  以上程序相当于以下定义:

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 GenericsDemo11{
    public static void main(String args[]){
        Info<Object> i = new Info<Object>() ;        // 指定Object为泛型类型
        i.setVar("MLDN") ;            // 设置字符串
        System.out.println("内容:" + i.getVar()) ;
    }
};
时间: 2024-10-02 11:43:33

泛型入门的相关文章

Java泛型入门

  Java泛型入门 在学习本章之前,须要对Java的集合(Collection.Map)有一定的基础. Java集合有一个缺点.就是把一个对象"丢进"集合里后,集合就会"忘记"这个对象的数据类型,当再次取出该对象时,该对象的编译类型就变成了Object类型(其执行时类型没变). 之所以这样设计是由于设计集合的程序猿不会知道我们要用它来保存什么类型的对象,所以这样设计具有非常好的通用性.可是这样做带来例如以下两个问题: l  集合对与元素类型没有限制,如一个集合

泛型(1)-泛型入门

一泛型的由来 Java集合有个缺点,把一个对象"丢进"集合里之后,集合就会"忘记"这个对象的数据类型,当再次取出该对象时候,该对象的编译类型就变成了Object类型(其运行时类型没变) Java集合之所以这样是因为设计者不知道我们使用集合会保存些什么类型的对象,故设计成能保存任何类型.带来了很好的通用性, 但带来了如下问题: 1.集合对元素类型没有任何限制.Dog与Cat都能存进一个集合中,有时候不方便. 2.将对象"丢进"集合中,集合丢失了对象

36_入门泛型的基本应用

  package com.itcast.day2; import java.lang.reflect.Constructor; import java.util.ArrayList; import java.util.List; /** * 泛型入门 * * @author ljl * */ public class GernericTest { public static void main(String[] args) throws Exception { /** * 不使用泛型时,ecl

面向对象,Java泛型篇

一.Java泛型入门基础 1. 泛型历史:集合中可以存储任意类型对象,但是在取出时,如果要使用具体对象的特有方法时,需要进行向下转型,如果存储的对象类型不一致,在转型过程中就会出现ClassCastException异常.这样就给程序带来了不安全性. 在jdk1.5以后就有了解决方案--泛型技术:在存储元素时,就不允许存储不同类型的元素.存储了就编译失败. 所以就需要在存储元素时,在容器上明确具体的元素类型,这其实和数组定义很像. 2.优势:1)将运行时期的ClassCastException异

30分钟泛型教程

一.泛型入门: 我们先来看一个最为常见的泛型类型List<T>的定义(真正的定义比这个要复杂的多,我这里删掉了很多东西) [Serializable] public class List<T> : IList<T>, ICollection<T>, IEnumerable<T> { public T this[int index] { get; set; } public void Add(T item); public void Clear()

java5核心基础泛型(2):泛型在反射中的应用

如何通过反射获取指定参数类型的构造函数? 贴代码如下: package highBasic.generic; /** * 泛型入门 */ import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Collection; public class GenericTest { public static void main(St

java5核心基础之泛型(1)

什么是泛型? 泛型是程序设计语言的一种特性.允许程序员在强类型程序设计语言中编写代码时定义一些可变部分,那些部分在使用前必须作出指明.各种程序设计语言和其编译器.运行环境对泛型的支持均不一样.将类型参数化以达到代码复用提高软件开发工作效率的一种数据类型.泛型类是引用类型,是堆对象,主要是引入了类型参数这个概念.(引自百科) 理解了以下代码,就会明白为何要用泛型! 下面还是直接贴出代码,看看这个java5的新特性,泛型的使用吧: package highBasic.generic; /** * 泛

疯狂Java讲义(第4版) PDF 电子书 百度云 网盘下载

java电子书推荐理由:1)作者提供用于学习和交流的配套网站及作者亲自在线的答疑微信群.QQ群. 2)DVD光盘中含 1500分钟图书部分内容的相关视频 图书配套代码 Java面试题真题 PPT课件 设计模式电子书 有助于完成课后练习的大量完整案例 3)<疯狂Java讲义>历时十年沉淀,现已升级到第4版,经过无数Java学习者的反复验证,被包括北京大学在内的大量985.211高校的优秀教师引荐为参考资料.选作教材. 4)<疯狂Java讲义>曾翻译为中文繁体字版,在宝岛台湾上市发行.

[.ashx檔?泛型处理程序?]基础入门#5....ADO.NET 与 将DB里面的二进制图片还原 (范例下载 &amp; 大型控件的ImageField)

[.ashx檔?泛型处理程序?]基础入门#5....ADO.NET 与 将DB里面的二进制图片还原 (范例下载 & 大型控件的ImageField) http://www.dotblogs.com.tw/mis2000lab/archive/2014/05/19/ashx_beginner_05_db_picture_show_download.aspx 根据前面三篇文章的教学 完成后可以做出来  (请您务必依照顺序学习,不要只是找范例来Copy) [.ashx檔?泛型处理程序?]基础入门#1.