Java 泛型

·  阅读 25

1 泛型方法

void <E> getSize( E e){}
复制代码

2 泛型类

 `class Test<T>{}`
复制代码

3 泛型限定 可以修饰类 也可以修饰方法
3.1 泛型限定

 `void <T extends Person> Text2(T t1 ,T t2){}` 
复制代码

3.2 泛型限定

  `void <T,V extends Person&Person2> Text2(T t1 ,T t2){}`
复制代码

限定类型 可以有类和接口,但是如果有类 必须写在第一个 ,并且有且只有一个类 ,可以有多个接口跟在后面 ,例如

Class Person{}
Interface PersonImpl1{}
Interface PersonImpl2{}
复制代码
void <T,V extends Person&PersonImpl1&PersonImpl2> Text2(T t1 ,T t2){}
复制代码

4 泛型的约束和局限性
4.1 泛型不能实例化 不能new 一个泛型 例如

 class Test<T>{
	Test(T t){
		t = new T();  // 这里是 错误的 不能实例化泛型
	}
 }
复制代码

4.2 静态方法 或 静态域 不能修饰泛型 例如

Private static T instance ; /错误的 
复制代码

对象在创建的时候 才知道泛型的具体类型,虚拟机在创建一个对象的时候 先执行的是类中的static 代码 ,在执行类的构造函数 所以还不知道泛型的具体类 ,所有不行。同时,静态方法中也不能引用泛型变量,
但是可以有静态的泛型方法 静态方法本身是泛型就是可以了 。

  static void <T> Text2(T t1 ){}
复制代码

4.3 基本类型不能当泛型是使用 ,例如 double不行 但是他的包装类Double 可以 ,因为double在java 中不是一个对象。

 class Test<T>{}

	Test<double> t1 = new Test(); // 编译报错
	Test<Double> t1 = new Test(); // 是对的
复制代码

4.4 泛型中不支持 instanceof 关键字
4.5 可以定义泛型数组,但是不是实例化(new)泛型数组
4.6 泛型类 不能 继承Exception

 class Test<T> extends Exception  { // 编译报错
 }
复制代码

4.7 泛型方法可以限定继承Throwable 但是不能抛出 泛型对象 例如

Public<T extends Throwable> void doWorkSuccess(T t){
	Try{
	}catch(T e){  // 这个地方会报错
	}
}
复制代码

4.8 泛型方法可以限定继承 Throwable 也可以抛出 Throwable 例如

Public<T extends Throwable> void doWorkSuccess(T x) throw T{
	Try{
	}catch(Throwable e){
		Thorw x ; // 可以跑出x
	}
}
复制代码

5 泛型的实例后 获取他的.getClass() 无论传的类型是什么 获取的class 都是一样的, 因为获取的是他的原生类型
6 泛型类型的继承规则
6.1 泛型分别中传入 子类 和 父类 这两个实例后的对象是 没有任何继承关系的
6.2 泛型类是可以继承的 例如

 List<String> list= new ArrayList<String>();
复制代码

7 泛型 通配符相关
7.1 在定义泛型类的时候 不能使用通配符 例如

Class Person<? extends Fruit>{} //这里是错误的 
Class Person<T extends Fruit>{} // 这个是 OK 的
 
复制代码

7.2 在方法中 传入一个泛型类 可以定义通配符 例如

Class Person<T>{
	private T t ;
	public T getT(){
		return t ;
	}
	public setT(T t){
		this.t = t ;
	}	
} 
复制代码
Class Fruit extents Food{}
Class Apple extents Fruit{}
Class Hongfushi extents Apple {}
复制代码
// 这里是可以的 ,代表传入的泛型的可以回Fruit和 他的子类 
Void test(Perosn<? extends Fruit> p){}  
复制代码
Person<Fruit> f1 = new Person();
Person<Apple> a2 = new Perosn();
Person<Food> food3 = new Perosn();
复制代码
test( f1); // 可以传入 对象 f1
Test( a2);// 可以传入 对象a2
// 报错 不可以传入 对象food3 应为上界就是 Fruit food 是Fruit 的父类 所以不能传入
Test( food3 );
复制代码

7.3

 Perosn<? extends Fruit> p 中 Fruit 是上界 只能传入他和他的子类
 Perosn<? super Apple > p 中 Apple 是下界 只能传入他和他的超类 
复制代码

可以传入 Apple ,Fruit 和 Food 但是不是传入他的子类Hongfushi

8 在虚拟机中会进行泛型的擦除
8.1例如 泛型的限定是 ArrayList & PersonImpl
低版本 Jdk会进行 泛型的擦除 (高的好想也擦除 ,大体这个意思吧) ,相当于 T 就是 ArrayList 但是因为还有 PersonImpl 在T调用 PersonImpl 的方式是 会进行强制转化 ,(PerosnImpl)t.xxx();

8.2 因为在jdk的编译器中会进行类型的擦除 ,所有在方法重载的时候 ,传入不同的泛型类型是不可以的 例如下面这样是不可以的

Void method(List<String> list){}
Void method(List<integer> list){}
复制代码
分类:
Android
标签:
分类:
Android
标签:
收藏成功!
已添加到「」, 点击更改