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<T,T1>{
	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<Apple>());  報錯,泛型沒有多態
		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() + " 類的實例");
		}
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章