Java 泛型

泛型

1. 泛型

1.1 什么是泛型
泛型的核心是让方法能够支持更多的类型,在满足多种条件情况下,又可以严格的遵守【数据类型一致化】

格式:
	<无意义单个大写英文字母占位符>
	占位符 ==> 数据类型
	常用泛型占位符:
		<T> Type 
		<E> Element
		<K> Key
		<V> Value
		<R> ReturnType

泛型操作主要涉及的内容
	1. 方法使用
	2. 类使用
	3. 接口使用
	【核心】都是为了约束方法。
1.2 泛型在方法中使用
格式:
	权限修饰符 static <自定义泛型无意义单个大写字母占位符> 返回值类型 方法名(形式参数列表) {
	
	}
【强制要求】
	1. 使用泛型的XX方法,要求形式参数列表中必须有一个参数对应的当前泛型。
	2. 返回值类型可以使用自定义泛型。
package com.qfedu.a;

public class Demo1 {
	public static void main(String[] args) {
		Integer t1 = testType(1);
		
		String t2 = testType("字符串???");
		
		Demo1 t3 = testType(new Demo1());
	}
	
	/**
	 * 带有自定义泛型的方法
	 * 
	 * @param <T> 自定义泛型无意义单个大写字母占位符
	 * @param t 自定义泛型对应的参数对象
	 * @return 对应泛型【约束】类型
	 */
	public static <T> T testType(T t) {
		return t;
	}
}
特征:
	1. 一个方法带有泛型,泛型对应的具体数据类型,是由当前方法中泛型参数来进行约束的。并且一旦确定无法更改【重
	点】
	2. 方法的返回值类型可以使用泛型。
	3. 方法中的局部变量可以使用自定义泛型。
package com.qfedu.a;

/*
 * 泛型案例演示
 */
public class Demo2 {
	public static void main(String[] args) {
		Integer[] arr1 = {1, 2, 3, 4, 5};
		String[] arr2 = {"西瓜", "桃子", "葡萄", "甘蔗", ""};
		Float[] arr3 = {1.4F, 2.5F, 3.5F};
		
		printArray(arr1);
		System.out.println("--------------------------");
		printArray(arr2);
		System.out.println("--------------------------");
		printArray(arr3);
	}
	
	/**
	 * 展示任意类型数组内容
	 * 
	 * @param <T> 自定义泛型占位符
	 * @param arr 需要展示的数组类型
	 */
	public static <T> void printArray(T[] arr) {
		for (int i = 0; i < arr.length; i++) {
			System.out.println(arr[i]);
		}
	}
}
1.3 泛型在类中使用
格式:
	class 类名<自定义无意义单个大写英文字母占位符> {
		类内的非静态成员方法可以使用类名声明的泛型。
		【类内的非静态成员变量不建议使用泛型】
	}
package com.qfedu.a;

/**
 * 一个类带有自定义泛型。
 * @author Anonymous
 *
 * @param <T> 自定义无意义泛型占位符
 */
class Type<T> {
	
	/**
	 * 当前方法的参数带有对应泛型
	 * 
	 * @param t 类名声明的自定义泛型
	 */
	public void test(T t) {
		// 获取当前参数的具体数据类型, 展示效果为完整的【包名.类名】
		System.out.println(t.getClass());
	}
	
	/**
	 * 当前方法要求参数为泛型约束类型,同时返回值类型也是泛型约束类型
	 * 
	 * @param t 类名声明泛型对应数据类型
	 * @return 同上
	 */
	public T getType(T t) {
		return t;
	}
	
	/*
	 * 静态成员方法是在类文件加载阶段,运行所需的所有内容全部准备就绪!!!要求方法
	 * 权限修饰,静态标记,返回值类型,方法名,形式参数列表和方法体全部准备就绪。已经可以执行。
	 * 通过类名调用
	 * 
	 * 当前类对应的泛型类型约束是需要通过 ==> 创建对象进行约束的!!!
	 * 
	 * 静态方法无法使用类名申明的泛型,因为加载时间不同,在类文件加载阶段无法明确泛型对应的具体类型。
	 * 
	 * 如果类内静态方法需要使用泛型,自己定义,自己使用!!!
	 * 建议:
	 * 		虽然泛型为无意义占位符,静态方法可以使用和类名同名的占位符,没有任何冲突。但是
	 * 		为了更好的代码阅读性,建议使用其他大写字母代替
	 */
	public static <A> A testStatic(A a) {
		return a;
	}
}

public class Demo4 {
	public static void main(String[] args) {
		/*
		 * 创建一个带有自定义泛型的类对象方式
		 * 两种风格:
		 * 		Eclipse:  Type<String> t1 = new Type<String>();
		 * 				明确告知当前Type<T>类型对象 t1 其中所有的泛型对应具体数据类型为String类型
		 * 		IDEA:  Type<String> t2 = new Type<>();
		 * 				明确告知当前Type<T>类型对象 t2 其中所有的泛型对应具体数据类型为String类型
		 */
		
		// 当前Type对象 t1 泛型对应具体数据类型为String类型
		Type<String> t1 = new Type<String>();
		t1.test("卤煮火烧+螺蛳粉+臭豆腐+臭鳜鱼");
		String string = t1.getType("豆汁+焦圈+煎饼果子");
		
		Type<Integer> t2 = new Type<Integer>();
		t2.test(10);
		int i = t2.getType(20);
		
		/*
		如果在创建Type对象时,没有给予对应泛型的具体约束。所有使用到泛型的位置都是Object类型
		方法可以继续运行,支持Java中所有类型,但是无法满足【数据类型一致化】。
		Type t3 = new Type();
		Object o1 = t3.getType(1);
		Object o2 = t3.getType("测试");
		Object o3 = t3.getType(3.5);
		Object o4 = t3.getType('a');
		*/
	}
}
1.4 泛型在接口中使用
格式:
	interface 接口名<自定义无意义泛型单个大写英文字母占位符> {
		接口中的成员变量无法使用接口声明的泛型,因为接口中的成员变量缺省属性 public static final
		要求定义时必须初始化!!!泛型在没有约束具体数据类型之前,无法明确类型,无法进行对应的赋值操作。
		
		接口中的成员方法 缺省类型 public abstract
	}
package com.qfedu.a;

interface A<T> {
	/**
	 * 接口内缺省属性 public abstract 当前方法可以使用自定义泛型。
	 * 
	 * @param t 自定义泛型无意义占位符
	 */
	void test(T t);

	/**
	 * default修饰方法也可以使用自定义泛型。
	 * @param t 自定义泛型类型
	 * @return 对应自定义泛型
	 */
	default public T getType(T t) {
		return t;
	}
}

/*
 * 类遵从带有泛型的接口两种模式:
 * 		1. 自由模式
 * 		2. 妻管严模式
 */

/*
 * 自由模式
 * 类名带有和接口同名泛型
 */
class TypeFreedom<T> implements A<T> {

	@Override
	public void test(T t) {
		System.out.println(t.getClass());
	}
	
}

/*
 * 妻管严模式
 * 遵从接口过程中,泛型已明确具体数据类型
 */
class TypeRakeEars implements A<String> {

	@Override
	public void test(String t) {
		System.out.println("当前泛型对应具体数据类型已明确为 String类型");
	}
	
}

public class Demo5 {
	public static void main(String[] args) {
		// 自由模式
		/*
		 * 在创建对象过程中,明确当前泛型对应的具体数据类型是一个
		 */
		TypeFreedom<Integer> t1 = new TypeFreedom<Integer>();
		t1.test(10);
		Integer integer = t1.getType(100);
		
		TypeFreedom<Demo5> t2 = new TypeFreedom<Demo5>();
		t2.test(new Demo5());
		Demo5 type = t2.getType(new Demo5());
		
		/*
		 * 妻管严模式
		 */
		TypeRakeEars 妻管严 = new TypeRakeEars();
		
		妻管严.test("让你往东,就必须往东!!!");
		String type2 = 妻管严.getType("在遵从接口时明确当前泛型为字符串");
	
	}

}
已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 深蓝海洋 设计师:CSDN官方博客 返回首页