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

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

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

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



进入正题:

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以及其父类Object
		System.out.print(temp + "xx") ;
	}
};

泛型与子类继承的限制:

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

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


如以下代码不行

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

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

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