泛型

泛型

1. 泛型案例

package com.qfedu.a;

public class Demo1 {
	public static void main(String[] args) {
		print(10);
		print(10.5);
		print(false);
	}
    
	/*
	 * 重载 reload
	 * 		1. 在同一个类内或者接口内
	 * 		2. 要求方法名必须一致
	 * 		3. 要求形式参数列表必须不一致。
	 * 		4. 返回值类型无要求
	 * JVM 会根据实际参数的数据类型,选择合适的方法执行。
	 * 【注意】
	 * 		形式参数列表不同,关注的是参数数据类型,非参数名称。
	 * 
	 * 以下方法	
	 * 		1. 功能一致
	 * 		2. 方法名称一致
	 * 不同点:
	 * 		参数类型不同。
	 * 
	 * 参数占位符!!!
	 
	public static void print(int num) {
		System.out.println("int参数方法");
		System.out.println(num);
	}
	
	public static void print(double num) {
		System.out.println("double参数方法");
		System.out.println(num);
	}
	
	public static void print(boolean ret) {
		System.out.println("boolean参数方法");
		System.out.println(ret);
	}
	*/
	public static <T> void print(T t) {
		System.out.println(t);
	}
}

2. 泛型格式

格式:
	<自定义无意义单个英文大写字母数据类型占位符>
常用:
	<T> Type 类型
	<E> Element 元素
	<K> Key 键
	<V> value 值
	<R> Return 返回值

泛型主要功能
	1. 增强方法,满足方法支持数据类型多样性,同时保证数据类型一致化。
	2. 泛型常用于【集合】
	3. 在 Stream 流开发中泛型存在大量使用。

任务:
	方法功能一致,有且只有数据类型不同,通过泛型约束,将数据类型的决定权交给用户操作,提升方法的能力,降低开发压力。

泛型主要出现的三个位置:
	1. 方法
	2. 类
	3. 接口

3. 泛型在方法中使用

格式:
	权限修饰符 [static] <自定义泛型占位符> 返回类型 方法名(形式参数列表) {
		方法体
	}
要求:
	1. 方法参数中必须有一个参数对应泛型类型,用于在用户调用当前方法时,传入的实际参数告知泛型对应的具体类型是哪一个。
	2. 方法的返回类型和方法体内局部变量可以使用自定义泛型。
	3. 单一方法使用泛型约束,方法参数必须有一个参数对应泛型类型。
	
tips:
	[static] 表示可有可无1
package com.qfedu.a;

public class Demo2 {
	public static void main(String[] args) {
		test(10);
		test(new Demo2());
		
		Demo2 demo2 = new Demo2();
		Double type = demo2.getType(1.5);
		String type2 = demo2.getType("你好泛型");
		Float type3 = demo2.getType(10.5F);
	}

	/**
	 * static 修饰静态成员方法,方法参数为自定义泛型 T
	 * 
	 * @param <T> 自定义泛型占位符
	 * @param t   用户传入的实际参数约束泛型对应的具体数据类型
	 */
	public static <T> void test(T t) {
		System.out.println(t);
	}

	/**
	 * 非 static 修饰的成员方法 ,方法的参数和返回值类型都是自定义泛型 T,
	 * 自定义泛型T 对应具体数据类型需要通过该方法调用过程中的实际参数来约束 
	 * 
	 * @param <T> 自定义泛型占位符
	 * @param t   用于传入的实际参数约束 T 对应的具体数据类型
	 * @return 用户传入实际参数约束返回值具体数据类型
	 */
	public <T> T getType(T t) {
		return t;
	}

}

4. 泛型在类中使用

格式:
	class 类<自定义泛型占位符> {
		类内成员方法可以使用类名声明的自定义泛型。
		静态成员方法是否可以使用类名声明的自定义泛型???
	}
package com.qfedu.a;

class TypeA<T> {
	/**
	 * 方法的参数和返回值类型都是类名声明的自定义泛型, 需要通过类对象来约束泛型对应的具体
	 * 数据类型。
	 * @param t 自定义泛型
	 * @return 自定义泛型
	 */
	public T getType(T t) {
		return t;
	}
	
	/**
	 * 方法的参数类型是自定义泛型类型,泛型对应的具体数据类型需要通过类对象约束。
	 * @param t 自定义泛型
	 */
	public void test(T t) {
		System.out.println(t);
	}
	
	/*
	 * 类内静态成员方法是否可以使用类名声明的泛型
	 * 
	 * 1. 静态成员方法在类文件加载阶段,已经具备执行能力,所有执行所需的必要内容都已经明确
	 * 权限修饰符,返回值类型,方法名,形式参数列表,方法体。
	 * 
	 * 2. 类名声明的泛型需要在创建对象过程中,约束泛型对应的具体数据类型,
	 * 
	 * 类内静态成员方法使用类名声明的泛型,直接报错。因为静态成员方法如果自定义泛型,可以通过方法
	 * 参数约束泛型对应的具体数据类型,从而保证方法在加载阶段已经具备执行能力。
	 * 但是使用类名声明的泛型,需要通过该实例化类对象约束对应数据类型,两者运行周期不同,无法合作,
	 * 导致冲突。
	 
	public static T staticMethod(T t) {
		return t;
	}*/ 
}

public class Demo3 {
	public static void main(String[] args) {
		/*
		 * 类名带有自定义泛型,泛型对应的具体数据类型,需要通过该创建类对象过程来
		 * 进行约束
		 * 格式:
		 * 		TypeA<String> t1 = new TypeA<String>();
		 * 		当前 TypeA 对象 t1 其中所有的泛型对应具体数据类型都是 String 类型。
		 */
		TypeA<String> t1 = new TypeA<String>();
		String str = t1.getType("字符串");
		t1.test("泛型通过该创建对象明确数据类型为 字符串类型 String");
		
		/*
		 * Integer 是对应基本数据类型 int 的包装类,在泛型中需要的类型不是基础类型,
		 * 需要类,这里可以使用 Integer 类等价于 int,而且 Integer 功能更强大
		 */
		TypeA<Integer> t2 = new TypeA<Integer>();
		
		Integer i = t2.getType(10);
		t2.test(200);
		
		/*
		 * 一个类带有自定义泛型,如果在创建对象过程中,没有明确泛型对应的具体数据类型,
		 * 所有使用到泛型的位置都是对应 Object 类型,该方式不符合泛型要求,不建议使用。
		 */
		TypeA t3 = new TypeA();
		Object obj = t3.getType(1000);
		t3.test("随便任意类型");
	}
}

5. 泛型在接口中使用

格式:
	interface 接口名<自定义泛型> {
		成员变量 缺省属性: public static final
			接口中的成员变量不可以使用自定义泛型,因为成员变量使用 final 修饰,需要在定义时必须初始化,如果使
			用泛型,无法明确数据类型,初始化任何数据无意义。所以成员变量不可以使用接口自定义泛型。
		成员方法 缺省属性: public abstract
		default修饰的默认方法有什么特征,必须有方法体
	}
5.1 妻管严模式
/*
 * 1. 妻管严模式
 * 		实现类遵从接口的过程中,接口直接明确泛型对应的具体数据类型。接口中所有方法使用到泛型
 * 约束的位置都是对应接口明确的数据类型。
 * 		实现类完成接口中所有缺省属性为 public abstract 修饰方法和重写default默认方法
 * 方法对应泛型位置都根据遵从接口过程中,明确泛型约束类型确定!!!
 */
class TypeB implements A<String> {

	@Override
	public String getType(String t) {
		// TODO Auto-generated method stub
		return t;
	}

	@Override
	public void test(String t) {
		// TODO Auto-generated method stub
		System.out.println(t);
	}
	
	@Override
	public String testDefault(String t) {
		return t;
    }
}
5.2 媳妇回娘家模式
/*
 * 2. 媳妇回娘家模式
 * 		实现类遵从接口过程中,接口没有明确泛型对应具体数据类型,同时类名声明和接口一致的泛型占位符。
 * 泛型对应具体数据类型,通过实例化实现类对象来进行约束,由调用者决定!!!
 */
class TypeC<T> implements A<T> {

	@Override
	public T getType(T t) {
		return t;
	}

	@Override
	public void test(T t) {
		System.out.println(t);
	}
	
}
TypeC<Integer> typeC = new TypeC<Integer>();         
                                                     
Integer i = typeC.getType(100);                      
typeC.test(200);                                     
System.out.println(i);                               
                                                     
Integer i2 = typeC.testDefault(500);                 
System.out.println(i2);                              
                                                     
TypeC<Demo4> typeC2 = new TypeC<Demo4>();            
                                                     
typeC2.test(new Demo4());                            
Demo4 testDefault2 = typeC2.testDefault(new Demo4());
Demo4 type = typeC2.getType(new Demo4());            
posted @ 2022-05-15 23:06  qtyanan  阅读(85)  评论(0编辑  收藏  举报