欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java 泛型(Generic)簡(jiǎn)介及用法詳解

 更新時(shí)間:2023年10月17日 10:21:16   作者:@Wenk  
泛型是一種把類型明確的工作推遲到創(chuàng)建對(duì)象或者調(diào)用方法的時(shí)候才去明確的特殊的類型,參數(shù)化類型,把類型當(dāng)作參數(shù)一樣的傳遞,本文給大家介紹Java 泛型(Generic)概述及使用,感興趣的朋友跟隨小編一起看看吧

引入:

看下面演示代碼測(cè)試

package cn.wen;
import java.util.ArrayList;
import java.util.Iterator;
public class GenericDemo1 {
	public static void main(String[] args) {
		// 創(chuàng)建
		ArrayList array = new ArrayList();
		// 添加元素
		array.add("hello");
		array.add("world");
		array.add("java");
		//array.add(new Integer(100));
		array.add(10); // JDK5以后的自動(dòng)裝箱
		// 等價(jià)于:array.add(Integer.valueOf(10));
		// 遍歷
		Iterator it = array.iterator();
		while (it.hasNext()) {
			// ClassCastException
			String s = (String) it.next();
			System.out.println(s);
		}
	}
}

 輸出異常:

hello
world
java
Exception in thread "main" java.lang.ClassCastException: class java.lang.Integer cannot be cast to class java.lang.String (java.lang.Integer and java.lang.String are in module java.base of loader 'bootstrap')
    at cn.wen.GenericDemo1.main(GenericDemo1.java:49)

 ArrayList存儲(chǔ)字符串并遍歷 
我們按照正常的寫法來寫這個(gè)程序, 結(jié)果確出錯(cuò)了。 為什么呢?因?yàn)槲覀冮_始存儲(chǔ)的時(shí)候,存儲(chǔ)了String和Integer兩種類型的數(shù)據(jù)。 而在遍歷的時(shí)候,我們把它們都當(dāng)作String類型處理的,做了轉(zhuǎn)換,所以就報(bào)錯(cuò)了。
但是,它在編譯期間卻沒有告訴我們。所以,就覺得這個(gè)設(shè)計(jì)的不好。
回想一下,我們的數(shù)組
         String[] strArray = new String[3];
        strArray[0] = "hello";
        strArray[1] = "world";
         strArray[2] = 10;

集合也模仿著數(shù)組的這種做法,在創(chuàng)建對(duì)象的時(shí)候明確元素的數(shù)據(jù)類型(字符串)。這樣就不會(huì)在有問題了。
而這種技術(shù)被稱為:泛型。

泛型:是一種把類型明確的工作推遲到創(chuàng)建對(duì)象或者調(diào)用方法的時(shí)候才去明確的特殊的類型。參數(shù)化類型,把類型當(dāng)作參數(shù)一樣的傳遞。
格式:
        <數(shù)據(jù)類型>
        此處的數(shù)據(jù)類型只能是引用類型。
 好處:
         A:把運(yùn)行時(shí)期的問題提前到了編譯期間
         B:避免了強(qiáng)制類型轉(zhuǎn)換
         C:優(yōu)化了程序設(shè)計(jì),解決了黃色警告線

Java 泛型

Java 泛型(generics)是 JDK 5 中引入的一個(gè)新特性, 泛型提供了編譯時(shí)類型安全檢測(cè)機(jī)制,該機(jī)制允許程序員在編譯時(shí)檢測(cè)到非法的類型。泛型的本質(zhì)是參數(shù)化類型,也就是說所操作的數(shù)據(jù)類型被指定為一個(gè)參數(shù)。

假定我們有這樣一個(gè)需求:寫一個(gè)排序方法,能夠?qū)φ蛿?shù)組、字符串?dāng)?shù)組甚至其他任何類型的數(shù)組進(jìn)行排序,該如何實(shí)現(xiàn)?答案是可以使用 Java 泛型。使用 Java 泛型的概念,我們可以寫一個(gè)泛型方法來對(duì)一個(gè)對(duì)象數(shù)組排序。然后,調(diào)用該泛型方法來對(duì)整型數(shù)組、浮點(diǎn)數(shù)數(shù)組、字符串?dāng)?shù)組等進(jìn)行排序。

修改上面代碼:正常輸出

package cn.wen;
 
import java.util.ArrayList;
import java.util.Iterator;
 
public class GenericDemo1 {
	public static void main(String[] args) {
		// 創(chuàng)建
		ArrayList<String> array = new ArrayList<String>();
 
		// 添加元素
		array.add("hello");
		array.add("world");
		array.add("java");
		//array.add(new Integer(100));
		//array.add(10); // JDK5以后的自動(dòng)裝箱
		// 等價(jià)于:array.add(Integer.valueOf(10));
 
		// 遍歷
		Iterator<String> it = array.iterator();
		while (it.hasNext()) {
			// ClassCastException
			//String s = (String) it.next();  //改進(jìn)如下
			String s = it.next();
			System.out.println(s);
		}
	}
}

 泛型在哪些地方使用呢?
         看API,如果類,接口,抽象類后面跟的有<E>就說要使用泛型。一般來說就是在集合中使用。

案例:

1)、用ArrayList存儲(chǔ)字符串元素,并遍歷。用泛型改進(jìn)代碼

package cn.wen_02;
 
import java.util.ArrayList;
import java.util.Iterator;
 
public class ArrayListDemo {
	public static void main(String[] args) {
		// 用ArrayList存儲(chǔ)字符串元素,并遍歷。用泛型改進(jìn)代碼
		ArrayList<String> array = new ArrayList<String>();
 
		array.add("hello");
		array.add("world");
		array.add("java");
 
		Iterator<String> it = array.iterator();
		while (it.hasNext()) {
			String s = it.next();
			System.out.println(s);
		}
		System.out.println("-----------------");
 
		for (int x = 0; x < array.size(); x++) {
			String s = array.get(x);
			System.out.println(s);
		}
	}
}

2)、需求:存儲(chǔ)自定義對(duì)象并遍歷。  

 A:創(chuàng)建學(xué)生類
 B:創(chuàng)建集合對(duì)象
 C:創(chuàng)建元素對(duì)象
 D:把元素添加到集合
 E:遍歷集合

package cn.wen_02;
import java.util.ArrayList;
import java.util.Iterator;
/*
 * 需求:存儲(chǔ)自定義對(duì)象并遍歷。
 * 
 * A:創(chuàng)建學(xué)生類
 * B:創(chuàng)建集合對(duì)象
 * C:創(chuàng)建元素對(duì)象
 * D:把元素添加到集合
 * E:遍歷集合
 */
public class ArrayListDemo2 {
	public static void main(String[] args) {
		// 創(chuàng)建集合對(duì)象
		// JDK7的新特性:泛型推斷。
		// ArrayList<Student> array = new ArrayList<>();
		// 但是我不建議這樣使用。
		ArrayList<Student> array = new ArrayList<Student>();
		// 創(chuàng)建元素對(duì)象
		Student s1 = new Student("小明", 40); 
		Student s2 = new Student("小東", 30); 
		Student s3 = new Student("小亮", 26);
		// 添加元素
		array.add(s1);
		array.add(s2);
		array.add(s3);
		// 遍歷
		Iterator<Student> it = array.iterator();
		while (it.hasNext()) {
			Student s = it.next();
			System.out.println(s.getName() + "---" + s.getAge());
		}
		System.out.println("------------------");
		for (int x = 0; x < array.size(); x++) {
			Student s = array.get(x);
			System.out.println(s.getName() + "---" + s.getAge());
		}
	}
}

學(xué)生類:

package cn.wen_02;
public class Student {
	// 姓名
	private String name;
	// 年齡
	private int age;
	public Student() {
		super();
	}
	public Student(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
}

泛型由來

為什么會(huì)有泛型呢 ?

  • 通過案例引入
  • 早期的Object類型可以接收任意的對(duì)象類型,但是在實(shí)際的使用中,會(huì)有類型轉(zhuǎn)換的問題。也就存在這隱患,所以Java提供了泛型來解決這個(gè)安全問題。

泛型應(yīng)用

  • 泛型類

把泛型定義在類上
格式 :public class 類名 < 泛型類型 1,…>
注意 : 泛型類型必須是引用類型

  • 泛 型方法

把泛型定義在方法上
格式 :public < 泛型類型 > 返回類型 方法名 ( 泛型類型 .)

  • 泛 型接口

• 把泛型定義在接口上
• 格式 :public  interface 接口名 < 泛型類型 1…>

泛型類的聲明和非泛型類的聲明類似,除了在類名后面添加了類型參數(shù)聲明部分。

和泛型方法一樣,泛型類的類型參數(shù)聲明部分也包含一個(gè)或多個(gè)類型參數(shù),參數(shù)間用逗號(hào)隔開。一個(gè)泛型參數(shù),也被稱為一個(gè)類型變量,是用于指定一個(gè)泛型類型名稱的標(biāo)識(shí)符。因?yàn)樗麄兘邮芤粋€(gè)或多個(gè)參數(shù),這些類被稱為參數(shù)化的類或參數(shù)化的類型。

泛型類:

package cn.wen_04;
 
/*
 * 泛型類:把泛型定義在類上
 */
public class ObjectTool<T> {
	private T obj;
 
	public T getObj() {
		return obj;
	}
 
	public void setObj(T obj) {
		this.obj = obj;
	}
}

測(cè)試類

package cn.wen_04;
/*
 * 泛型類的測(cè)試
 */
public class ObjectToolDemo {
	public static void main(String[] args) {
		// ObjectTool ot = new ObjectTool();
		//
		// ot.setObj(new String("風(fēng)清揚(yáng)"));
		// String s = (String) ot.getObj();
		// System.out.println("姓名是:" + s);
		//
		// ot.setObj(new Integer(30));
		// Integer i = (Integer) ot.getObj();
		// System.out.println("年齡是:" + i);
		// ot.setObj(new String("林青霞"));
		// // ClassCastException
		// Integer ii = (Integer) ot.getObj();
		// System.out.println("姓名是:" + ii);
		System.out.println("-------------");
		ObjectTool<String> ot = new ObjectTool<String>();
		// ot.setObj(new Integer(27)); //這個(gè)時(shí)候編譯期間就過不去
		ot.setObj(new String("林青霞"));
		String s = ot.getObj();
		System.out.println("姓名是:" + s);
		ObjectTool<Integer> ot2 = new ObjectTool<Integer>();
		// ot2.setObj(new String("風(fēng)清揚(yáng)"));//這個(gè)時(shí)候編譯期間就過不去
		ot2.setObj(new Integer(27));
		Integer i = ot2.getObj();
		System.out.println("年齡是:" + i);
	}
}

實(shí)例

如下實(shí)例演示了我們?nèi)绾味x一個(gè)泛型類:

public class Box<T> {
  private T t;
  public void add(T t) {
    this.t = t;
  }
  public T get() {
    return t;
  }
  public static void main(String[] args) {
    Box<Integer> integerBox = new Box<Integer>();
    Box<String> stringBox = new Box<String>();
    integerBox.add(new Integer(10));
    stringBox.add(new String("HolleWorld"));
    System.out.printf("整型值為 :%d\n\n", integerBox.get());
    System.out.printf("字符串為 :%s\n", stringBox.get());
  }
}

2、泛型方法

你可以寫一個(gè)泛型方法,該方法在調(diào)用時(shí)可以接收不同類型的參數(shù)。根據(jù)傳遞給泛型方法的參數(shù)類型,編譯器適當(dāng)?shù)靥幚砻恳粋€(gè)方法調(diào)用。

下面是定義泛型方法的規(guī)則:

  • 所有泛型方法聲明都有一個(gè)類型參數(shù)聲明部分(由尖括號(hào)分隔),該類型參數(shù)聲明部分在方法返回類型之前(在下面例子中的<E>)。
  • 每一個(gè)類型參數(shù)聲明部分包含一個(gè)或多個(gè)類型參數(shù),參數(shù)間用逗號(hào)隔開。一個(gè)泛型參數(shù),也被稱為一個(gè)類型變量,是用于指定一個(gè)泛型類型名稱的標(biāo)識(shí)符。
  • 類型參數(shù)能被用來聲明返回值類型,并且能作為泛型方法得到的實(shí)際參數(shù)類型的占位符。
  • 泛型方法體的聲明和其他方法一樣。注意類型參數(shù)只能代表引用型類型,不能是原始類型(像int,double,char的等)。

泛型方法類:

package cn.itcast_05;
//未使用泛型之前
//public class ObjectTool<T> {
//	// public void show(String s) {
//	// System.out.println(s);
//	// }
//	//
//	// public void show(Integer i) {
//	// System.out.println(i);
//	// }
//	//
//	// public void show(Boolean b) {
//	// System.out.println(b);
//	// }
//
//	public void show(T t) {
//		System.out.println(t);
//	}
// }
/*
 * 泛型方法:把泛型定義在方法上
 */
public class ObjectTool {
	public <T> void show(T t) {
		System.out.println(t);
	}
}

 測(cè)試泛型方法類:

package cn.wen_05;
public class ObjectToolDemo {
	public static void main(String[] args) {
		// ObjectTool ot = new ObjectTool();
		// ot.show("hello");
		// ot.show(100);
		// ot.show(true);
		// ObjectTool<String> ot = new ObjectTool<String>();
		// ot.show("hello");
		//
		// ObjectTool<Integer> ot2 = new ObjectTool<Integer>();
		// ot2.show(100);
		//
		// ObjectTool<Boolean> ot3 = new ObjectTool<Boolean>();
		// ot3.show(true);
		// 說明泛型類是沒有問題的
		// 但是呢,誰說了我的方法一定要和類的類型的一致呢?
		// 要是類上沒有泛型的話,方法還能不能接收任意類型的參數(shù)了呢?
		// 定義泛型方法后
		ObjectTool ot = new ObjectTool();
		ot.show("hello");
		ot.show(100);
		ot.show(true);
	}
}

實(shí)例

下面的例子演示了"extends"如何使用在一般意義上的意思"extends"(類)或者"implements"(接口)。該例子中的泛型方法返回三個(gè)可比較對(duì)象的最大值。

public class MaximumTest
{
   // 比較三個(gè)值并返回最大值
   public static <T extends Comparable<T>> T maximum(T x, T y, T z)
   {                     
      T max = x; // 假設(shè)x是初始最大值
      if ( y.compareTo( max ) > 0 ){
         max = y; //y 更大
      }
      if ( z.compareTo( max ) > 0 ){
         max = z; // 現(xiàn)在 z 更大           
      }
      return max; // 返回最大對(duì)象
   }
   public static void main( String args[] )
   {
      System.out.printf( "%d, %d 和 %d 中最大的數(shù)為 %d\n\n",
                   3, 4, 5, maximum( 3, 4, 5 ) );
      System.out.printf( "%.1f, %.1f 和 %.1f 中最大的數(shù)為 %.1f\n\n",
                   6.6, 8.8, 7.7, maximum( 6.6, 8.8, 7.7 ) );
      System.out.printf( "%s, %s 和 %s 中最大的數(shù)為 %s\n","pear",
         "apple", "orange", maximum( "pear", "apple", "orange" ) );
   }
}
3, 4 和 5 中最大的數(shù)為 5
6.6, 8.8 和 7.7 中最大的數(shù)為 8.8
pear, apple 和 orange 中最大的數(shù)為 pear

3、泛型接口

 接口類:

package cn.wen_06;
/*
 * 泛型接口:把泛型定義在接口上
 */
public interface Inter<T> {
	public abstract void show(T t);
}

實(shí)現(xiàn)類: 

package cn.wen_06;
//實(shí)現(xiàn)類在實(shí)現(xiàn)接口的時(shí)候
//第一種情況:已經(jīng)知道該是什么類型的了
//public class InterImpl implements Inter<String> {
//
//	@Override
//	public void show(String t) {
//		System.out.println(t);
//	}
// }
//第二種情況:還不知道是什么類型的
public class InterImpl<T> implements Inter<T> {
	@Override
	public void show(T t) {
		System.out.println(t);
	}
}

測(cè)試類:

package cn.wen_06;
public class InterDemo {
	public static void main(String[] args) {
		// 第一種情況的測(cè)試
		// Inter<String> i = new InterImpl();
		// i.show("hello");
		// // 第二種情況的測(cè)試
		Inter<String> i = new InterImpl<String>();
		i.show("hello");
		Inter<Integer> ii = new InterImpl<Integer>();
		ii.show(100);
	}
}

泛型高級(jí)(通配符)

  • 泛型通配符<?>

任意類型,如果沒有明確,那么就是 Object 以及任意的 Java 類了

  • ? extends E

向下限定, E 及其子類

  • ? super E

向上限定, E 及其父類

package cn.wen;
import java.util.ArrayList;
import java.util.Collection;
/*
 * 泛型高級(jí)(通配符)
 * ?:任意類型,如果沒有明確,那么就是Object以及任意的Java類了
 * ? extends E:向下限定,E及其子類
 * ? super E:向上限定,E極其父類
 */
public class GenericDemo {
	public static void main(String[] args) {
		// 泛型如果明確的寫的時(shí)候,前后必須一致
		Collection<Object> c1 = new ArrayList<Object>();
		// Collection<Object> c2 = new ArrayList<Animal>();
		// Collection<Object> c3 = new ArrayList<Dog>();
		// Collection<Object> c4 = new ArrayList<Cat>();
		// ?表示任意的類型都是可以的
		Collection<?> c5 = new ArrayList<Object>();
		Collection<?> c6 = new ArrayList<Animal>();
		Collection<?> c7 = new ArrayList<Dog>();
		Collection<?> c8 = new ArrayList<Cat>();
		// ? extends E:向下限定,E及其子類
		// Collection<? extends Animal> c9 = new ArrayList<Object>();//報(bào)錯(cuò)
		Collection<? extends Animal> c10 = new ArrayList<Animal>();
		Collection<? extends Animal> c11 = new ArrayList<Dog>();
		Collection<? extends Animal> c12 = new ArrayList<Cat>();
		// ? super E:向上限定,E極其父類
		Collection<? super Animal> c13 = new ArrayList<Object>();
		Collection<? super Animal> c14 = new ArrayList<Animal>();
		// Collection<? super Animal> c15 = new ArrayList<Dog>();
		// Collection<? super Animal> c16 = new ArrayList<Cat>();
	}
}
class Animal {
}
class Dog extends Animal {
}
class Cat extends Animal {
}

到此這篇關(guān)于Java 泛型(Generic)概述及使用的文章就介紹到這了,更多相關(guān)Java 泛型內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java異常報(bào)錯(cuò):java.nio.file.FileSystemException的多種解決方案

    Java異常報(bào)錯(cuò):java.nio.file.FileSystemException的多種解決方案

    在Java應(yīng)用程序中處理文件和目錄時(shí),java.nio.file.FileSystemException是一個(gè)常見的異常,這個(gè)異常發(fā)生在嘗試進(jìn)行文件系統(tǒng)操作時(shí),本文將詳細(xì)探討FileSystemException的成因,并提供多種解決方案,需要的朋友可以參考下
    2024-12-12
  • 利用feign調(diào)用返回object類型轉(zhuǎn)換成實(shí)體

    利用feign調(diào)用返回object類型轉(zhuǎn)換成實(shí)體

    這篇文章主要介紹了利用feign調(diào)用返回object類型轉(zhuǎn)換成實(shí)體,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • JWT整合Springboot的方法步驟

    JWT整合Springboot的方法步驟

    本文主要介紹了JWT整合Springboot的方法步驟,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-11-11
  • @CacheEvict + redis實(shí)現(xiàn)批量刪除緩存

    @CacheEvict + redis實(shí)現(xiàn)批量刪除緩存

    這篇文章主要介紹了@CacheEvict + redis實(shí)現(xiàn)批量刪除緩存方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • JAVA模擬新增順序表及單鏈表

    JAVA模擬新增順序表及單鏈表

    這篇文章主要介紹了JAVA模擬新增順序表及單鏈表,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-07-07
  • 解決java.util.NoSuchElementException異常正確方法

    解決java.util.NoSuchElementException異常正確方法

    java.util.NoSuchElementException是Java中的一種異常,表示在迭代器或枚舉中找不到元素,這篇文章主要給大家介紹了關(guān)于解決java.util.NoSuchElementException異常的相關(guān)資料,需要的朋友可以參考下
    2023-11-11
  • 使用Java讀取Word文件的簡(jiǎn)單例子分享

    使用Java讀取Word文件的簡(jiǎn)單例子分享

    這篇文章主要介紹了使用Java讀取Word文件的簡(jiǎn)單例子分享,包括讀取word文件的表格數(shù)據(jù)的示例,需要的朋友可以參考下
    2015-10-10
  • Java多線程start()方法原理解析

    Java多線程start()方法原理解析

    這篇文章主要介紹了Java多線程start()方法原理解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-11-11
  • Ajax實(shí)現(xiàn)搜索引擎自動(dòng)補(bǔ)全功能

    Ajax實(shí)現(xiàn)搜索引擎自動(dòng)補(bǔ)全功能

    本文主要介紹了Ajax實(shí)現(xiàn)搜索引擎自動(dòng)補(bǔ)全功能的實(shí)例解析。具有很好的參考價(jià)值。下面跟著小編一起來看下吧
    2017-04-04
  • Java調(diào)用打印機(jī)的2種方式舉例(無驅(qū)/有驅(qū))

    Java調(diào)用打印機(jī)的2種方式舉例(無驅(qū)/有驅(qū))

    我們平時(shí)使用某些軟件或者在超市購物的時(shí)候都會(huì)發(fā)現(xiàn)可以使用打印機(jī)進(jìn)行打印,這篇文章主要給大家介紹了關(guān)于Java調(diào)用打印機(jī)的2種方式,分別是無驅(qū)/有驅(qū)的相關(guān)資料,需要的朋友可以參考下
    2023-11-11

最新評(píng)論