java 泛型

        想必大家都有过这么个经历,当我们是采用面向对象的方法开发时,我们的增删该查,面对不同的实体,其实操作都差不多,或者可以是一样,在例如我要表示一个点,我可以写Point(String sx,String sy),也可以写成Point(Double dx,Double y),其实就是里边的参数类型不一样,其他的可能都一样,这个时候jdk就给了我们一个很好的解决方案,泛型。

       泛型就是解决我们累心转换的问题,尤其是在编译期间不出问题,但是却会在程序运行时报错的问题,例如下边一段代码:

public void test(){
		List list = new ArrayList();
		list.add(32);
		list.add("menghaibin");
		list.add(32.222);
	}
      这个泛型方法在编译的时候是不会报错的,因为list.add()方法里边的参数类型是Object,而所有的类型的基类是object,所以程序编译不报错,但是如果程序运行呢,例如上边的代码,就一定会包错,并且是类型转化失败 java.lang.ClassCastException的错误了。原因很简单,我第一次加的是事一个int类型,那么以后就业应该加,而且即使我以前写的对了,我在取值的时候也需要强转一下,前提是类型我还能记得住。二这个时候我们来看看泛型为我们带来了什么。

泛型类

       假如我要表示一个点,可能是坐标,也可能是位置,例如下边的代码:

    public class Demo {
        public static void main(String[] args){
            // 实例化泛型类
            Point<Integer, Integer> p1 = new Point<Integer, Integer>();
            p1.setX(10);
            p1.setY(20);
            int x = p1.getX();
            int y = p1.getY();
            System.out.println("This point is:" + x + ", " + y);
           
            Point<Double, String> p2 = new Point<Double, String>();
            p2.setX(25.4);
            p2.setY("东京180度");
            double m = p2.getX();
            String n = p2.getY();
            System.out.println("This point is:" + m + ", " + n);
        }
    }
    // 定义泛型类
    class Point<T1, T2>{
        T1 x;
        T2 y;
        public T1 getX() {
            return x;
        }
        public void setX(T1 x) {
            this.x = x;
        }
        public T2 getY() {
            return y;
        }
        public void setY(T2 y) {
            this.y = y;
        }
    }
      与普通类的定义相比,上面的代码在类名后面多出了 <T1, T2>,T1, T2 是自定义的标识符,也是参数,用来传递数据的类型,而不是数据的值,我们称之为 类型参数。在泛型中,不但数据的值可以通过参数传递,数据的类型也可以通过参数传递。T1, T2 只是数据类型的占位符,运行时会被替换为真正的数据类型。
       类型参数需要在类名后面给出。一旦给出了类型参数,就可以在类中使用了。类型参数必须是一个合法的标识符,习惯上使用单个大写字母,通常情况下,K 表示键,V 表示值,E 表示异常或错误,T 表示一般意义上的数据类型。当然类型参数只能表示引用类型,而不能表示基本类型,包括int,Double等,但是我们编写程序的时候不会报错,因为程序会对他进行装箱成对应的包装类。例如int--》Integer.

       泛型方法和接口

      当然泛型还有这么一个用途,就是泛型方法,也就是说我们不用把泛型限制在类上,在接口上,在方法上都是可以得。

    public class Demo {
        public static void main(String[] args){
            // 实例化泛型类
            Point<Integer, Integer> p1 = new Point<Integer, Integer>();
            p1.setX(10);
            p1.setY(20);
            p1.printPoint(p1.getX(), p1.getY());
           
            Point<Double, String> p2 = new Point<Double, String>();
            p2.setX(25.4);
            p2.setY("东京180度");
            p2.printPoint(p2.getX(), p2.getY());
        }
    }
    // 定义泛型类
    class Point<T1, T2>{
        T1 x;
        T2 y;
        public T1 getX() {
            return x;
        }
        public void setX(T1 x) {
            this.x = x;
        }
        public T2 getY() {
            return y;
        }
        public void setY(T2 y) {
            this.y = y;
        }
       
        // 定义泛型方法
        public <T1, T2> void printPoint(T1 x, T2 y){
            T1 m = x;
            T2 n = y;
            System.out.println("This point is:" + m + ", " + n);
        }
    }
     运行结果:
This point is:10, 20
This point is:25.4, 东京180度

泛型擦除

如果在使用泛型时没有指明数据类型,那么就会擦除泛型类型,请看下面的代码:

    public class Demo {
        public static void main(String[] args){
            Point p = new Point();  // 类型擦除
            p.setX(10);
            p.setY(20.8);
            int x = (Integer)p.getX();  // 向下转型
            double y = (Double)p.getY();
            System.out.println("This point is:" + x + ", " + y);
        }
    }
    class Point<T1, T2>{
        T1 x;
        T2 y;
        public T1 getX() {
            return x;
        }
        public void setX(T1 x) {
            this.x = x;
        }
        public T2 getY() {
            return y;
        }
        public void setY(T2 y) {
            this.y = y;
        }
    }
      这里还有一个小技巧,那就是extends来限制返回值的类型。代码如下:
    public <T extends Number> T getMax(T array[]){
        T max = null;
        for(T element : array){
            max = element.doubleValue() > max.doubleValue() ? element : max;
        }
        return max;
    }

     <T extends Number> 表示 T 只接受 Number 及其子类,传入其他类型的数据会报错。这里的限定使用关键字 extends,后面可以是类也可以是接口。但这里的 extends 已经不是继承的含义了,应该理解为 T 是继承自 Number 类的类型,或者 T 是实现了 XX 接口的类型。

       说了这么多,大家对泛型的认识和使用应该有一个大概的了解吧,其实泛型就是对我们的参数尽心了一个封装,尽量让我们的代码重用性提高。




  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值