java泛型知识整理

一、泛型基本概念
1、什么是泛型
泛型就是参数化类型,使用广泛的类型;声明时使用泛型,使用时指定具体类型

2、泛型常见的字母及对应含义
T :Type表示类型
K V:分别表示键值对中的key和value
E:表示Element元素类型
? :表示不确定的类型

3、泛型的优点:省心、安全
(1)安全:在编译时检查类型安全
(2)省心:所有的强制转换都是自动和隐式的,同一套代码可以用于多种数据类型,提高代码的重用率

public class Student<T1,T2> {
     
	private T1 name;
	private T2 age;
	
	
	public T1 getName() {
     
		return name;
	}

	public void setName(T1 name) {
     
		this.name = name;
	}

	public T2 getAge() {
     
		return age;
	}

	public void setAge(T2 age) {
     
		this.age = age;
	}

	public static void main(String[] args) {
     
		//使用时指定类型
		Student<String,Integer> stu = new Student<String,Integer>();
		//安全:类型检查
		stu.setName("张三");
		//stu.setAge("20");  类型检查报错
		//省心:类型转换
		String str = stu.getName();
	}
	
}

4、泛型类
泛型类:定义类时使用泛型,使用时确定类型
注意事项:
1、泛型声明时不能使用在静态属性和静态方法上(因为静态方法属性在编译时确定类型)
2、泛型字母只能使用引用类型,不能使用基本类型

package cn.cjy.generics;
/**
 * 泛型类:定义类时使用泛型,使用时确定类型
 * 1、泛型声明时不能使用在静态属性和静态方法上(因为静态方法属性在编译时确定类型)
 * 2、泛型字母只能使用引用类型,不能使用基本类型
 */
public class Student<T1,T2> {
     
	private T1 name;
	private T2 age;
	
	
	public T1 getName() {
     
		return name;
	}

	public void setName(T1 name) {
     
		this.name = name;
	}

	public T2 getAge() {
     
		return age;
	}

	public void setAge(T2 age) {
     
		this.age = age;
	}


	public static void main(String[] args) {
     
		//使用时指定类型
		Student<String,Integer> stu = new Student<String,Integer>();
		//安全:类型检查
		stu.setName("张三");
		//stu.setAge("20");  类型检查报错
		//省心:类型转换
		String str = stu.getName();
	}
	
}

5、泛型接口
接口中,泛型字母只能使用在方法中,不能使用在全局常量中

/**
 * 泛型接口:接口中,泛型字母只能使用在方法中,不能使用在全局常量中
 *
 */
public interface Comparator<T> {
     
	void comparator(T t); 
}

6、泛型方法
泛型方法<>:定义在返回类型前面
1、只能访问对象信息,不能修改对象信息
2、extends <=:表示T只能是Closeable及其子类 (…表示可变参数)

package cn.cjy.generics;

import java.io.Closeable;
import java.io.IOException;

/**
 * 泛型方法<>:定义在返回类型前面
 * 1、只能访问对象信息,不能修改对象信息
 * 2、extends <=:表示T只能是Closeable及其子类  (...表示可变参数)
 * 
 */
public class MethodTest {
     
	public static void main(String[] args) {
     
		test("测试"); // T-->String
	}
	
	//泛型方法
	public static <T> void test(T t){
     
		System.out.println(t);
	}
	
	//extends <=:表示T只能是Closeable及其子类  (...表示可变参数)
	public static <T extends Closeable> void test(T... t){
     
		for(T temp:t){
     
			try {
     
				if(null!=temp){
     
					temp.close();
				}
			} catch (IOException e) {
     
				e.printStackTrace();
			}
		}
	}

}

二、泛型的使用
1、父类为泛型类的继承
(1)属性类型:在父类中属性类型随父类定,在子类中属性类型随子类定
(2)重写方法类型:随父类而定
(3)泛型擦除:要么子类、父类同时擦除,要么子类>=父类类型,不能子类擦除父类泛型
a、继承或实现不指定类型
b、使用时不指定类型,统一Object类型对待,但是不完全等同于Object,编译时不会类型检查

package cn.cjy.generics;
/**
 * 父类为泛型类
 * 1、属性
 * 2、方法
 *泛型擦除:要么子类、父类同时擦除,要么子类>=父类类型,不能子类擦除父类泛型
 *1、属性类型:在父类中属性类型随父类定,在子类中属性类型随子类定
 *2、重写方法类型:随父类而定
 */
public abstract class Father<T,T1> {
     
	T name;
	public abstract void test(T t);
}
/**
 * 子类声明时指定具体类型
 * 1、属性类型为具体类型
 * 2、方法类型为具体类型
 */
class child1 extends Father<String,Integer>{
     
	String str;
	@Override
	public void test(String t) {
     
		
	}
}

/**
 * 子类为泛型类,类型在使用时确定
 * 子类的泛型个数大于等于父类,父类有的子类都要要
 * 
 */
class child2<T,T1,T2> extends Father<T,T1>{
     
	T1 t1;
	@Override
	public void test(T t) {
     
	}
}

/**
 * 泛型的擦除:子类为泛型类,父类不指定类型,重写方法使用Object替换泛型
 * 
 */
class child3<T,T1> extends Father{
     
	T1 t1;
	@Override
	public void test(Object t) {
     		
	}
}

/**
 * 子类与父类泛型同时擦除:子类为泛型类,父类不指定类型,重写方法使用Object替换泛型
 * 
 */
class child4 extends Father{
     
	String name;
	@Override
	public void test(Object t) {
     		
	}
}

/**
 * 子类擦除,父类使用泛型:错误的使用
 * 
class child4 extends Father{
	String name;
	@Override
	public void test(Object t) {		
	}
}
 */

2、泛型接口的实现

package cn.cjy.generics;
/**
 * 泛型接口
 * 重写方法类型随父类而定
 *
 */
public interface Comparator01<T> {
     
	void compare(T t);
}
//声明子类指定具体类型
class test implements Comparator01<String>{
     

	@Override
	public void compare(String t) {
     		
	}
	
}

//父类子类同事擦除
class test1 implements Comparator01{
     

	@Override
	public void compare(Object t) {
     
		
	}	
}

//父类擦除,子类泛型
class test2<T> implements Comparator01{
     

	@Override
	public void compare(Object t) {
     
		
	}	
}

//子类泛型>=父类泛型
class test3<T,T1> implements Comparator01<T>{
     

	@Override
	public void compare(T t) {
     
		
	}	
}

3、泛型实现多态效果:使用通配符?

(1)多态,泛型没有多态!

package cn.cjy.generics;
/**
 * 多态
 * 1、形参多态
 * 3、返回类型多态
 *
 */
public class Fruit {
     
	
}

class Apple extends Fruit{
     
	
}

class Test{
     
	public static void main(String[] args) {
     
		Fruit f = new Apple();
	}
	//形参使用多态
	public static void test1(Fruit t){
     
		
	}
	
	//返回类型使用多态
	public static Fruit test2(){
     
		return new Apple();
	}
}

(2)泛型使用通配符?
a、类型不定,使用时确定类型
b、可以用在声明类型、声明方法参数上,不能用在声明类上或者使用时
c、可以接收泛型的任意类型,只能接收和输出,不能修改
d、? extends 泛型上限 <= 指定类型为自身或子类
e、? super 泛型下限 >= 指定类型为自身或父类

package cn.cjy.generics;
/**
 * 通配符?的使用:
 * 1、类型不定,使用时确定类型
 * 2、可以用在声明类型、声明方法参数上,不能用在声明类上或者使用时
 * 3、可以接收泛型的任意类型,只能接收和输出,不能修改
 * 4、? extends 泛型上限  <=
 * 5、? super 泛型下限   >=
 *
 */
public class StudentTest<T> {
     
	T score;
	
	public static void main(String[] args) {
     
		StudentTest<?> stu = new StudentTest<String>();
		test(new StudentTest<String>());
		test1(new StudentTest<Apple>());  //类似与多态的效果
		//test2(new StudentTest());  报错,泛型没有多态
		test3(new StudentTest<Object>()); 
	}
	
	public static void test(StudentTest<?> stu){
     
		
	}
	
	public static void test1(StudentTest<? extends Fruit> stu){
     
		
	}
	
	public static void test2(StudentTest<Fruit> stu){
     
		
	}
	
	public static void test3(StudentTest<? super Fruit> stu){
     
		
	}
}

4、泛型嵌套

package cn.cjy.generics;
/**
 * 泛型嵌套 
 * 
 */
public class TestNest<T> {
     
	T stu;
	public static void main(String[] args) {
     
		//泛型的嵌套
		TestNest<StudentTest<String>> test = new TestNest<StudentTest<String>>();
		//从外到内拆封
		test.stu = new StudentTest<String>();
		StudentTest<String> stu = test.stu;
		String score = stu.score;
		System.out.println(score);
	}
}

三、注意事项
1、泛型没有多态
2、没有泛型数组,声明可以使用,不能创建泛型数组

四、instanceof用法总结
instanceof用于测试左边的对象是否是右边的类或其子类的实例,返回 boolean 的数据类型

package cn.cjy.generics;
/**
 * instanceof的用法
 */
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;
 
public class TestInstanceof {
     
 
	public static void main(String[] args) {
     
		
	   List list = new ArrayList();
	   test(list);
	}
    public static void test(Object o) {
     
		if (o instanceof Vector){
     
			System.out.println("对象是 Vector类的实例");
		}
		else if (o instanceof ArrayList){
     
			System.out.println("对象是ArrayList类的实例");
		}
		else{
     
			System.out.println("对象是 " + o.getClass() + " 类的实例");
		}
    }
}

你可能感兴趣的:(java开发,java)