java泛型学习-泛型的产生原因,使用方法以及具体的警告

来源:互联网 发布:java程序员职位描述 编辑:程序博客网 时间:2024/05/22 05:23

如果缺乏能力,自由反而是一种负担   --使用Ubuntu有感

看魔乐的李兴华JAVA视频,视频倒是几年前百度云就存好了,也放在电脑上好久了.最近在重新补习JAVA,正好翻到了这些视频,

从接受的角度而言,视频讲解比看书要容易得多,只是自己一直有一种强迫症似的感觉,喜欢看书学习.

殊不知这是效率最低的方法,今天学的知识点其实时一个小时就能搞懂的知识点,但是因为知识缺陷的原因此前看到别的代码里面的泛型,都是头大的看不懂.

学习啊!方法很重要,不能有知识缺陷,先不求深入,但是框架脉络总得捋一遍.
今天甚至翻到了B站竟然有一系列的学习IT相关的视频,感觉对B站越来越有好感了,都是一些很有趣的视频,不会让人有心理负担.其实,我这么逃避学习大概是因为怕自己投入了也学不好,所以干脆逃避,o,the biggest deny is delay!!


进入正题:

1为什么要有泛型?保证数据的安全性

特别是如果在一个类内部,成员变量一开始不知道用的时候会赋值为什么类型的时候,会非常头痛,类型转换也是个大问题.


2因此在类名的旁边声明一个类型,用字母加尖括号表示,<T>,而这个T可以在类内部使用,编译运行的时候替换成具体的类型.简单的说,就是使用类的时候先声明泛型的类型;


通过这种方式,在使用类的时候可以声明构造的类中该泛型表示的具体的类型,减少类型转换的操作,更加安全,如果赋值与声明的类型不一质量,则编译的时候就会报错.


可以通过构造方法为成员变量赋值,这样的好处时不需要进行多次的构造方法的重载,直接一个泛型替代了


3在类中可以执行多个泛型的,在尖括号中指定

class xxx<a,b,c>{

}



4泛型的安全警告

在使用带泛型的类的时候,没有指定泛型的类型,会有编译警告.因为不确定传入的时什么值,但不会影响执行,因为在java中为了不影响使用,如果没有指定泛型的类型,就会将T替换成Object,




泛型的通配符

1泛型对象进行引用传递的时候,类型必须一致,如果现在非要传递,可以将方法的参数中的泛型类型取消掉,,


2可以用?来代替


3使用<?>只能接收,不能修改???

class Info<T>{private T var ;public void setVar(T var){this.var = var ;}public T getVar(){return this.var ;}public String toString(){return this.var.toString() ;}};public class GenericsDemo15{public static void main(String args[]){Info<?> i = new Info<String>() ;//单此一句用问号接收这个类型的对象是可以 i.setVar("MLDN") ;//但是加上这一句赋值的就编译报错.}};



4通配符的限制

受限泛型:在引用传递中,泛型操作可以设置一个泛型对象的范围上限和范围下限,范围上限使Eextends关键字声明,表示参数化的类型可能是说指定的类型或者此类型的子类,

而范围下限使用super声明,表示来参数化类型可能是指定的类型或者时次类型的父类型,直至object类.


class Info<T>{private T var ;public void setVar(T var){this.var = var ;}public T getVar(){return this.var ;}public String toString(){// Ö±½Ó´òÓ¡return this.var.toString() ;}};public class GenericsDemo18{public static void main(String args[]){Info<String> i1 = new Info<String>() ;// i1.setVar("hello") ;fun(i1) ;}public static void fun(Info<? extends Number> temp){// 最多只能传递到NUMBER这一类型System.out.print(temp + "¡¢") ;}};
//--------------------------------------------------分割线
class Info<T extends Number>{//只能传递数字private T var ;// public void setVar(T var){this.var = var ;}public T getVar(){return this.var ;}public String toString(){// return this.var.toString() ;}};public class GenericsDemo19{public static void main(String args[]){Info<Integer> i1 = new Info<Integer>() ;// 正确的
Info<String> i1 = new Info<String>() ;//错误的 
                }};


泛型的下限:

class Info<T>{private T var ;// 定义泛型变量public void setVar(T var){this.var = var ;}public T getVar(){return this.var ;}public String toString(){// 直接打印return this.var.toString() ;}};public class GenericsDemo21{public static void main(String args[]){Info<String> i1 = new Info<String>() ;//声明String的泛型对象Info<Object> i2 = new Info<Object>() ;// 声明Object的泛型对象i1.setVar("hello") ;i2.setVar(new Object()) ;fun(i1) ;fun(i2) ;}public static void fun(Info<? super String> temp){// 只能接收String以及其父类ObjectSystem.out.print(temp + "xx") ;}};
泛型与子类继承的限制:

一个类的子类可以通过对象多态性,为其父类实例化,但是在泛型操作中,子类的泛型时无法使用父类的泛型类型来接受的,例如

Info<String> 不能使用 Info<Object>接收,就是泛型使用必须精准,上下限只起到一个枚举的作用


如以下代码不行

Info<String> i1 = new Info<String>() ;
Info<Object> i2 = null ;
i2 = i1 ;

这样会扩大子类中类型,不行

但是使用?可以接收任意的泛型对象.







原创粉丝点击