泛型

来源:互联网 发布:无人机推荐 知乎 编辑:程序博客网 时间:2024/06/07 01:42

 一、对于泛型,也许你想知道,我们为什么要用泛型,或者换句话说,使用泛型的原因是什么?

     我觉得之所以使用泛型,是因为为了提高代码的重用性,我们知道,Object是对象中最高层次的基类,也是有类型的,那么对于某些情况下,我们不需要知道它的确定类型,或简而言之,没有指定类型,只有在运行时,从运行的结果我们才知道具体的类型是什么,就这样,泛型雪中送炭来了。

二、对于泛型的基础了解,首先我们要知道的几个知识点:

1.类型参数化,就是泛型的别名,正如一个人有别名一样,比如张三的别名叫二柱子等;
2.泛型,是允许对类型进行抽象的,我们知道对类型进行抽象化,可以提高代码的健壮性,比如,一个人是允许通过运动来提高我们免疫力,从而让自己变得非常强壮的;
3.泛型的好处是什么呢?前面说过,程序在编译时,是能够对该类型进行检查的,并且所有的强制转换都是自动和隐式进行的,由于是自动的,无须人为操作,同时由于是隐式的,也看不出什么来,但可以提高代码的重用性。
4.泛型类
4.1>在JDK1.5及以后的版本中,才增设了泛型,其泛型类的格式为:泛型类体名<T>{类体},其中T代表一个类型的名称。
4.2>应用泛型类创建对象时,可以根据实际的需要去指定<T>的类型,这样做的好处是,当你在使用类的方法传递参数或返回值时就不再需要进行类型的转换操作,而是直接在创建对象时<>符号中设置的数据类型即可,让得我们提高了效率;同时,我们要有一点了解,jdk之所以更新版本,要么是变得更方便了,要么是提高效率了,还要么是提高了安全性。
∇注意:

我们要知道的是,泛型的类型参数只能是类类型(包括自定义类),不能是简单的数据类型。

由于参数类型的这种不确定性,也就存在着同一种泛型可以对应多个版本的现象,造成不同版本的泛型类实例是不兼容的。所以要注意泛型的类型参数只能是类类型的。

实践:




package com.wsq.www;
/*
* 增强对泛型的理解
*/
public class Test <T>
{
        T Obj;//定义成员变量obj为T类型
        public T getB()//定义getXXX()成员方法的返回值类型为T类型
        {
                return Obj;
        }
        public void setB(T obj)//定义setXXX()成员方法的参数为T类型
        {Obj=obj;}
        public static void main(String[] args) {
       //实例化一个Boolean型的对象
                Test<Boolean> b=new Test<Boolean>();
                //实例化一个Float型的对象
                Test<Float> f=new Test<Float>();
                b.setB(false);
                Boolean bb=b.getB();
                f.setB(23.4f);
                Float ff=f.getB();
                System.out.print(bb);
                System.out.println(";"+ff);


        }


}


运行结果:
false;23.4


5.泛型的常用方法
5.1>同时声明多个类型参数,其语法格式为:
多参数泛型类名<T1,T2>
{
多参数泛型类体
}
5.2>声明数组类型参数
在定义泛型类时也可以用数组作为参数
5.3>受限泛型
受限泛型定义格式为:
class 泛型类名<T extends 受限类型>
例如"class Info<T extends Number>"中的参数T受限于只能是Number类型或其子类,若传入非Number类型或其子类编译时将会出现错误,这就是限制泛型的目的。
∇注意:
<T extends Number>中的关键字extends,后面可以是类也可以是接口。extends已不再具有继承的含义,而是指T类型被限制为只能是Number类型或其子类型。
5.4>泛型通配符
为了解决泛型受限过死的缺点,Java泛型提供了"泛型通配符",使用泛型通配符的格式为:
<? extends 某类型>
其中,?是泛型通配符,<? extends 某类型>表示未知类型,在需要创建该泛型类的对象时,可以单独实例化。
∇注意:
泛型通配符只能用于引用的声明,不能在创建对象时使用;不能采用泛型通配符的引用调用使用了泛型参数的方法。

5.5>实现泛型的接口

比如:定义了一个public interface Generator<T>{public  T  next()}这样的生成器接口,然后再定义一个生成器类来实现这个接口,比如我定义一个汽车生成器来实现这个接口:

public class CarGenerator implements Generator<String>

{ private String[] cars=new String[]{"BenChi","baoma","aodi","dazhong"};

public String next(){

Random rand=new Random();

return cars[rand.nextInt(4)];

}

}

//将输出打印语句封装在sop函数内,方便调用,简化代码

public static void sop(Object object){
System.out.println(object);
}

最后在主函数内用

public class MainDemo{

public static void main(String[] args){

CarGenerator generator=new CarGenerator();

sop(generator.next());

sop(generator.next());

sop(generator.next());

sop(generator.next());

}

输出:

BenChi

baoma

baoma

baoma

总之,记住一个role:如果在实际情况下,凡是有机会能够将整个类泛化,别犹豫了,直接使用泛型方法。因为这样可以让简化我们的工作,毕竟对类型的判断和处理本来是由我们做的,现在我们指挥编译器去做这些,趁着编译器做这项工作的功夫,也许我们可以来杯咖啡喝喝,惬意与舒服,享受程序给我们带来的快乐。希望彼此共同坚持一个信仰:

The code change the world.

原创粉丝点击