Java 泛型

一、泛型定义

        泛型是Java SE 1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。这种参数类型可以用在类、接口和方法的创建中,分别称为泛型类、泛型接口、泛型方法。 Java语言引入泛型的好处是安全简单。

        在Java SE 1.5之前,没有泛型的情况的下,通过对类型Object的引用来实现参数的“任意化”,“任意化”带来的缺点是要做显式的强制类型转换,而这种转换是要求开发者对实际参数类型可以预知的情况下进行的。对于强制类型转换错误的情况,编译器可能不提示错误,在运行的时候才出现异常,这是一个安全隐患。

        泛型的好处是在编译的时候检查类型安全,并且所有的强制转换都是自动和隐式的,以提高代码的重用率。

二、规范限制

1、泛型的类型参数只能是类类型(包括自定义类),不能是简单类型。

2、同一种泛型可以对应多个版本(因为参数类型是不确定的),不同版本的泛型类实例是不兼容的。

3、泛型的类型参数可以有多个。

4、泛型的参数类型可以使用extends语句,例如<T extends superclass>。习惯上称为“有界类型”。

5、泛型的参数类型还可以是通配符类型。例如Class<?> classType = Class.forName("java.lang.String");

三、用法实例

这个实例包括了Java泛型基本所有的用例,不会的多看几遍,如果你都能理解,那么泛型就算学完了。如果有什么疑问欢迎在我博客下面留言。

package com.chy.genertic;

import java.io.Serializable;
import java.util.ArrayList;

public class Class_1 {
	public class Class_A {}
	public class Class_B extends Class_A{}
	public class Class_C extends Class_B{}
	
	public Class<?>[] testArray1 = {Class_A.class, Class_B.class, Class_C.class};
	
//	//error: Cannot create a generic array of Class<? extends Class_1.Class_B>
//	public Class<? extends Class_B>[] testArray2 = {Class_A.class, Class_B.class, Class_C.class};
	
//	//error: Multiple markers at this line
//	//(1)- Type mismatch: cannot convert from Class<Class_1.Class_C> to Class<? super Class_1.Class_B>
//	//(2)- Cannot create a generic array of Class<? super Class_1.Class_B>
//	public Class<? super Class_B>[] testArray3 = {Class_A.class, Class_B.class, Class_C.class};
	
//	//数组是不能通过泛型创建的,因为我们不能创建不可具体化的类型的数组
//	//error: Multiple markers at this line
//	//(1)- T cannot be resolved to a type
//	//(2)- Type mismatch: cannot convert from Class<Class_1.Class_A> to Class<T>
//	//(3)- Type mismatch: cannot convert from Class<Class_1.Class_B> to Class<T>
//	//(4)- Type mismatch: cannot convert from Class<Class_1.Class_C> to Class<T>
//	//(5)- Cannot create a generic array of Class<T>
//	public Class<T>[] testArray4 = {Class_A.class, Class_B.class, Class_C.class};

	public Class_1() {
//		//error: Type mismatch: cannot convert from ArrayList<Class_1.Class_A> to ArrayList<? extends Class_1.Class_B>
//		ArrayList<? extends Class_B> testArray5 = new ArrayList<Class_A>();
		ArrayList<? extends Class_B> testArray6 = new ArrayList<Class_B>();
		ArrayList<? extends Class_B> testArray7 = new ArrayList<Class_C>();
//		//error: The method add(capture#4-of ? extends Class_1.Class_B) in the type List<capture#4-of ? extends Class_1.Class_B> is not applicable for the arguments (Class_1.Class_A)
//		testArray6.add(new Class_A());
//		//error: The method add(capture#5-of ? extends Class_1.Class_B) in the type List<capture#5-of ? extends Class_1.Class_B> is not applicable for the arguments (Class_1.Class_B)
//		testArray6.add(new Class_B());
//		//error: The method add(capture#6-of ? extends Class_1.Class_B) in the type List<capture#6-of ? extends Class_1.Class_B> is not applicable for the arguments (Class_1.Class_C)
//		testArray6.add(new Class_C());
		
		ArrayList<? super Class_B> testArray8 = new ArrayList<Class_A>();
		ArrayList<? super Class_B> testArray9 = new ArrayList<Class_B>();
//		//error: Type mismatch: cannot convert from ArrayList<Class_1.Class_C> to ArrayList<? super Class_1.Class_B>
//		ArrayList<? super Class_B> testArray10 = new ArrayList<Class_C>();
//		//error: The method add(capture#7-of ? super Class_1.Class_B) in the type List<capture#7-of ? super Class_1.Class_B> is not applicable for the arguments (Class_1.Class_A)
//		testArray9.add(new Class_A());
		testArray9.add(new Class_B());
		testArray9.add(new Class_C());
		
		test12(Class_B.class);
		test12(new Class_B());
	}
	
	public void test1(Class<?> cls) {}
	
	public void test2(Class<Integer> cls) {}
	
//	//error: Syntax error on token "int", Dimensions expected after this token
//	public void test3(Class<int> cls) {}
	
	//为了解决类型被限制死了不能动态根据实例来确定的缺点,引入了“通配符泛型”,针对上面的例子,使用通配泛型格式为<? extends Collection>,“?”代表未知类型
	public void test4(Class<? extends Class_B> cls) { }
	
//	//error: T cannot be resolved to a type
//	public void test5(Class<T> cls) { }
	
//	//error: T cannot be resolved to a type
//	public void test6(T cls) { }
	
//	//wran: The type parameter T should not be bounded by the final type String. Final types cannot be further extended
//	public <T extends String> void test7(Class<T> cls) { }
	
	public <T extends Object> void test8(Class<T> cls) { }
	
	//extends 统一的表示了原有的 extends 和 implements 的概念,但仍要遵循应用的体系,Java 只能继承一个类,但可以实现多个接口
	public <T extends Object & Serializable> void test9(Class<T> cls) { }
	
	//通配符泛型不单可以向下限制,如<? extends Collection>,还可以向上限制,如<? super Double>,表示类型只能接受Double及其上层父类类型,如Number、Object类型的实例。
	public void test10(Class<? super Class_B> cls) {}
	
//	//error: Multiple markers at this line
//	//(1)- Syntax error on token "super", ,  expected
//	//(2)- T cannot be resolved to a type
//	public <T super Integer> void test11(Class<T> cls) {}
	
	public <T> void test12(T cls) {}
	
	public class Class_2<T> {
		
		//如果只指定了<?>,而没有extends,则默认是允许Object及其下的任何Java类了。也就是任意类
		public void test1(Class<?> cls) { }
		
		//参数类型的可能是T或是T的子类
		public void test2(T cls) { }
		
//		//wran: The type parameter T is hiding the type T
//		public <T extends Object> void test3(Class<T> cls) { }
		
		//? 通配符类型,<? extends T> 表示类型的上界,表示参数化类型的可能是T或是T的子类
		public void test4(Class<? extends T> cls) { }
		
		//? 通配符类型,<? super T> 表示类型下界(Java Core中叫超类型限定),表示参数化类型是此类型的超类型(父类型),直至Object
		public void test5(Class<? super T> cls) { }
		
		public <S> void test6(S cls) { }
		
//		//error: Multiple markers at this line
//		//(1)- Syntax error on token "?", invalid Type
//		//(2)- Syntax error on token "?", invalid TypeParameter
//		//(3)- Syntax error on token(s), misplaced construct(s)
//		public <? extends T> void test7(? cls) {}
		
		public <E extends T> void test8(E cls) {}
		
//		//error: Multiple markers at this line
//		//(1)- Syntax error on token "super", , expected
//		//(1)- S cannot be resolved to a type
//		public <S super T> void test9(S cls) {}
	}
	
	public class Class_3 extends Class_1 {
		
		public Class_3 () {
			Class_1 cls = new Class_1();
			Class<?> class_A_correct = null;
			try {
				class_A_correct = Class.forName("com.demo.test.Class_1.Class_A");
			} catch (ClassNotFoundException e) {
				e.printStackTrace();
			}
			Class_A cls_A_error = new Class_A();
			
			cls.test1(null);
			cls.test1(Class_A.class);
			cls.test1(class_A_correct);
//			//error: The method test1(Class<?>) in the type Class_1 is not applicable for the arguments (Class_1)
//			cls.test1(cls);
//			//error: The method test1(Class<?>) in the type Class_1 is not applicable for the arguments (Class_1.Class_A)
//			cls.test1(cls_A_error);
		}
	}
	
//	//Class_1.Class_2 is a raw type. References to generic type Class_1.Class_2<T> should be parameterized
//	public class Class_4 extends Class_2{}
	
//	//warn: Multiple markers at this line
//	//(1)- Class_1.Class_2 is a raw type. References to generic type Class_1.Class_2<T> should be parameterized
//	//(2)- The type parameter Integer is hiding the type Integer
//	public class Class_5<Integer> extends Class_2{}
	
	public class Class_5 extends Class_2<Class_B> {
		public Class_5() {
			Class_A cls_A = new Class_A();
			Class_B cls_B = new Class_B();
			Class_C cls_C = new Class_C();
			
//			//error: The method test2(Class_1.Class_B) in the type Class_1.Class_2<Class_1.Class_B> is not applicable for the arguments (Class_1.Class_A)
//			super.test2(cls_A);
			super.test2(cls_B);
			super.test2(cls_C);
			
//			//error: The method test4(Class<? extends Class_1.Class_B>) in the type Class_1.Class_2<Class_1.Class_B> is not applicable for the arguments (Class<Class_1.Class_A>)
//			super.test4(Class_A.class);
			super.test4(Class_B.class);
			super.test4(Class_C.class);
			
			super.test5(Class_A.class);
			super.test5(Class_B.class);
//			//error: The method test5(Class<? super Class_1.Class_B>) in the type Class_1.Class_2<Class_1.Class_B> is not applicable for the arguments (Class<Class_1.Class_C>)
//			super.test5(Class_C.class);
			
//			//Bound mismatch: The generic method test7(E) of type Class_1.Class_2<T> is not applicable for the arguments (Class_1.Class_A). The inferred type Class_1.Class_A is not a valid substitute for the bounded parameter <E extends Class_1.Class_B>
//			super.test8(cls_A);
			super.test8(cls_B);
			super.test8(cls_C);
		}
	}

}
提示:class<? extends Object>表示的是一个类型;而<T extends Object>表示的是一个对象。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值