小白学Java之对泛型的理解

    科技2024-10-27  20

    首先提到的是,这篇博客参考自《Effective java》和一篇鼎鼎有名的博客: https://blog.csdn.net/s10461/article/details/53941091

    首先是我对于泛型这个概念的理解:

    顾名思义,也就是广泛的类型,也就是不是具体指向某一个类型,就相当于“参数化类型”,一般就是先有类或者接口的名称,在加一个尖括号(<>)来具体指向实际的类型,比如List,也就是特指list中的Strng.使得存放的时候更精确,在运行之前就能发现存在错误与否。

    这也就引出了一个很有意思的点,泛型的适用类型: 先写一段代码:

    import java.util.ArrayList; import java.util.List; public class test2020926{ public static void main(String[] args) { List<String> stringArrayList=new ArrayList<String>(); List<Integer> integerArrayList=new ArrayList<Integer>(); Class classStringArrayList=stringArrayList.getClass(); Class classStringArraylist=integerArrayList.getClass(); if(classStringArrayList.equals(classStringArraylist)){ //判断两个是不是同一个类型 System.out.println("两个类型是一样的"); } } }

    这段代码最后的输出就是“两个类型是一样的”,所以***证明在编译之后程序会采取去泛型化的措施,也就是Java的泛型只在编译阶段有效,编译结束,不出现错误之后,就会把对应的相关信息擦去,不会进入到运行阶段***。

    接着就是对于泛型的使用情况

    泛型类泛型接口泛型方法

    首先第一个就是泛型类:他一般就是

    class 类名称<泛型的标识>{ }

    举个“更生动”的例子

    public class Generic<T>{ //这里T是需要指定类型的 private T key; public Genaric(T key){ this.key=key; } //再还有方法 public T getkey(){ return key; } }

    值得注意的是,这里的T,可以是指定类型,并且指定了就需要传入指定的参数,比如:

    Generic<String> ge=new Generic<String>("key");

    传入的是String,参数里也是String类型

    也可以不指定参数类型,根据传入的泛型实参做相应的限制。比如:

    Generic generic=new Generic(222);

    再者就是泛型接口: 他的定义和泛型类其实差不太多,毕竟接口就可以当做是特殊类。 而接口除了定义以外,还有另一个重要的功能就是被实现,于是就出现两种情况。 1.当实现泛型接口的类 ,未传入泛型的实参,比如

    class A<T> implements G<T>{ }

    需要在A这边也声明,不然会报错 2.当实现泛型接口的类,传入泛型实参 class B implements G{ } 这里B就不需要声明了,并且要把G里面的方法也同样替代成传入的String类型。

    再介绍方法之前,介绍一下***泛型通配符*** 其实就是

    List<?>

    这种类型。并且这个?,可以看作是一个类型实参,就是那种和Sring Integer一样的类型,直接当成所有类的父类都行。

    最后是泛型方法 最重要的一句话

    只有声明了的方法才是泛型方法,泛型类中的使用了泛型的成员方法并不是泛型方法

    public <T> T showKeyName(Generic<T> container){ System.out.println("container key :" + container.getKey()); //当然这个例子举的不太合适,只是为了说明泛型方法的特性。 T test = container.getKey(); return test; }

    这个模式才是最正确的 PS,还有个静态方法与泛型: 如果静态方法要使用泛型的话,必须将静态方法也定义成泛型方法,用代码表示就是:

    public class StaticGenerator<T> { .... .... /** * 如果在类中定义使用泛型的静态方法,需要添加额外的泛型声明(将这个方法定义成泛型方法) * 即使静态方法要使用泛型类中已经声明过的泛型也不可以。 * 如:public static void show(T t){..},此时编译器会提示错误信息: "StaticGenerator cannot be refrenced from static context" */ public static <T> void show(T t){ } }

    总之就是需要在方法上 也加一个 T

    最后一句话,泛型在我看来,最大的作用还是在于提高代码的规范性。

    Processed: 0.009, SQL: 8