您的位置:首页 > 编程语言 > Java开发

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

2017-12-17 20:43 423 查看
如果缺乏能力,自由反而是一种负担   --使用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替换成Objec
bbdf
t,

泛型的通配符
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以及其父类Object
System.out.print(temp + "xx") ;
}
};泛型与子类继承的限制:
一个类的子类可以通过对象多态性,为其父类实例化,但是在泛型操作中,子类的泛型时无法使用父类的泛型类型来接受的,例如
Info<String> 不能使用 Info<Object>接收,就是泛型使用必须精准,上下限只起到一个枚举的作用

如以下代码不行
Info<String> i1 = new Info<String>() ;

Info<Object> i2 = null ;
i2 = i1 ;

这样会扩大子类中类型,不行
但是使用?可以接收任意的泛型对象.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐