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

Java泛型T,E,K,V,N,?與Object區(qū)別和含義

 更新時(shí)間:2022年03月09日 15:30:58   作者:不想起床的小張  
Java?泛型(generics)是?JDK?5?中引入的一個(gè)新特性,?泛型提供了編譯時(shí)類型安全檢測(cè)機(jī)制,該機(jī)制允許程序員在編譯時(shí)檢測(cè)到非法的類型。本文將詳細(xì)講講Java泛型T、E、K、V、N、?和Object區(qū)別和含義,需要發(fā)可以參考一下

通常我們?cè)诳匆恍┰创a時(shí),發(fā)現(xiàn)全是T、?,暈乎乎的:sob:。于是,把泛型掌握好十分重要!

什么是泛型

Java 泛型(generics)是 JDK 5 中引入的一個(gè)新特性, 泛型提供了編譯時(shí)類型安全檢測(cè)機(jī)制,該機(jī)制允許程序員在編譯時(shí)檢測(cè)到非法的類型。

泛型的本質(zhì)是參數(shù)化類型,也就是說(shuō)所操作的數(shù)據(jù)類型被指定為一個(gè)參數(shù)。

泛型有什么好處?寫個(gè)例子一目了然:

我們要封裝一個(gè)消息響應(yīng)類:

public class Result implements Serializable {

    // 響應(yīng)碼
    Integer code;

    // 是否成功
    Boolean success;

    // 返回體數(shù)據(jù)
    User user;

    public Result(Integer code, Boolean success, User user) {
        this.code = code;
        this.success = success;
        this.user = user;
    }

    @Override
    public String toString() {
        return "Result{" +
                "code=" + code +
                ", success=" + success +
                ", user=" + user +
                '}';
    }

    public static void main(String[] args) {

        User user = new User(1, "Tony");
        Result result = new Result(200, true, user);
        System.out.println(result);

    }

}

class User implements Serializable {

    Integer id;

    String name;

    public User(Integer id, String name) {
        this.id = id;
        this.name = name;

    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }
}
Result{code=200, success=true, user=User{id=1, name='Tony'}}

進(jìn)程已結(jié)束,退出代碼0

呼~這樣這個(gè)反應(yīng)體就可以返回請(qǐng)求狀態(tài)和用戶信息了。可現(xiàn)在需求又需要返回關(guān)于手機(jī)的信息,那我們又得封裝一個(gè)能返回手機(jī)信息的響應(yīng)類了...到后面還有衣服、鞋子...那不得累死?這時(shí)候泛型登場(chǎng)了:

public class Result<T> implements Serializable {

    // 響應(yīng)碼
    Integer code;

    // 是否成功
    Boolean success;

    // 返回體數(shù)據(jù)
    T data;

    public Result(Integer code, Boolean success, T data) {
        this.code = code;
        this.success = success;
        this.data = data;
    }

    @Override
    public String toString() {
        return "Result{" +
                "code=" + code +
                ", success=" + success +
                ", data=" + data +
                '}';
    }

    public static void main(String[] args) {

        User user = new User(1, "Tony");
        Result<User> resultUser = new Result<>(200, true, user);
        System.out.println(resultUser);
        Phone phone = new Phone(999.99, "Yellow");
        Result<Phone> resultPhone = new Result<>(200, true, phone);
        System.out.println(resultPhone);

    }

}

class User implements Serializable {

    Integer id;

    String name;

    public User(Integer id, String name) {
        this.id = id;
        this.name = name;

    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }
}

class Phone implements Serializable {

    Double price;

    String color;

    @Override
    public String toString() {
        return "Phone{" +
                "price=" + price +
                ", color='" + color + '\'' +
                '}';
    }

    public Phone(Double price, String color) {
        this.price = price;
        this.color = color;
    }
}
Result{code=200, success=true, data=User{id=1, name='Tony'}}
Result{code=200, success=true, data=Phone{price=999.99, color='Yellow'}}

進(jìn)程已結(jié)束,退出代碼0

可見(jiàn),利用泛型,可以統(tǒng)一標(biāo)識(shí)需要返回的實(shí)體類。不管你來(lái)什么類,我都可以給你塞進(jìn)去!

第一次接觸可能看不太明白,下面就詳細(xì)講解

泛型方法

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

語(yǔ)法規(guī)則

所有泛型方法聲明都有一個(gè)類型參數(shù)聲明部分(由尖括號(hào)分隔),該類型參數(shù)聲明部分在方法返回類型之前

比如說(shuō)這是一個(gè)用來(lái)打印數(shù)組的泛型方法:

private static <E> void printArray(E[] inputArray)

每一個(gè)類型參數(shù)聲明部分包含一個(gè)或多個(gè)類型參數(shù),參數(shù)間用逗號(hào)隔開(kāi)。一個(gè)泛型參數(shù),也被稱為一個(gè)類型變量,是用于指定一個(gè)泛型類型名稱的標(biāo)識(shí)符。

比如這個(gè)方法

private static <E,T> void printArray(E[] inputArray, T data)

類型參數(shù)能被用來(lái)聲明返回值類型,并且能作為泛型方法得到的實(shí)際參數(shù)類型的占位符。

泛型方法體的聲明和其他方法一樣。注意類型參數(shù)只能代表引用型類型,不能是原始類型(int double char等)

泛型標(biāo)記符

  • E Element 集合元素
  • T Type Java類
  • K Key 鍵
  • V Value 值
  • N Number 數(shù)值類型
  • ? 表示不確定的Java類型

這些標(biāo)記并不是限定只有對(duì)應(yīng)的類型才能使用,即使你統(tǒng)一使用A-Z英文字母的其中一個(gè),編譯器也不會(huì)報(bào)錯(cuò)。之所以又不同的標(biāo)記符,這是一種**約定。**在開(kāi)發(fā)中很多規(guī)則都是一種約定,它能提高我們代碼的可讀性,方便團(tuán)隊(duì)見(jiàn)的合作開(kāi)發(fā)

寫個(gè)完整的例子:

public class TFunction {

    public static void main(String[] args) {

        // 創(chuàng)建各種類型的數(shù)組
        Integer[] intArray = {1, 2, 3, 4, 5};
        Double[] doubleArray = {1.1, 2.2, 3.3, 4.4};
        Character[] charArray = {'H', 'E', 'L', 'L', 'O'};

        System.out.println("整型數(shù)組元素為:");
        printArray(intArray); // 傳遞一個(gè)整型數(shù)組

        System.out.println("\n雙精度型數(shù)組元素為:");
        printArray(doubleArray); // 傳遞一個(gè)雙精度型數(shù)組

        System.out.println("\n字符型數(shù)組元素為:");
        printArray(charArray); // 傳遞一個(gè)字符型數(shù)組

    }

    // 泛型方法
    private static <E> void printArray(E[] inputArray) {

        // 遍歷打印數(shù)組
        Arrays.stream(inputArray).forEach(e -> {
            System.out.printf("%s ", e);
        });
        System.out.println();

    }
    
}

泛型類

泛型類的聲明與非泛型類幾乎相同,唯一的不同在于類名的后面添加了參數(shù)聲明部分

這邊就不舉例子了,因?yàn)殚_(kāi)篇的例子就是封裝了一個(gè)泛型類,當(dāng)時(shí)不太理解的可以再回去看一下

類型通配符

?

我們一般可以使用?來(lái)承接所有的引用類型,搬運(yùn)一個(gè)菜鳥(niǎo)上的例子:

public class GenericTest {
     
    public static void main(String[] args) {
        List<String> name = new ArrayList<String>();
        List<Integer> age = new ArrayList<Integer>();
        List<Number> number = new ArrayList<Number>();
        
        name.add("icon");
        age.add(18);
        number.add(314);
 
        getData(name);
        getData(age);
        getData(number);
       
   }
 
   public static void getData(List<?> data) {
      System.out.println("data :" + data.get(0));
   }
}
data :icon
data :18
data :314

?extends T

這是**泛型上邊界:**只有T對(duì)象的子類可以被傳入

如果是? extends C,那么只有D和E允許被傳入,否則會(huì)編譯報(bào)錯(cuò)

? super T

這是**泛型下邊界:**只有T對(duì)象的父類可以被傳入

如果是? super D,那么只有C和A允許被傳入,否則會(huì)編譯報(bào)錯(cuò)

T 和 ?

不知道看到這里,有沒(méi)有疑惑。T和?好像作用差不多啊,有什么區(qū)別?

這里解釋一下,T一般作為泛型參數(shù),而?是更多是用來(lái)一個(gè)不確定的引用類型,意會(huì)一下吧~~~

T 和 Object

重頭戲?。?/p>

知道的Object的同志都了解其是Java的超類(所有對(duì)象的父類),不了解的可以去看看我的博客,有做詳細(xì)的解釋。

那么問(wèn)題就來(lái)了,Object好像可以代替泛型的功能?。∷心苡玫椒盒偷牡胤絆bject都可以!

其實(shí),在JDK5之前,都是用的Object,但其存在很多的問(wèn)題,JDK5之后便引入了泛型

Object是所有類的父類,在編碼過(guò)程中就難免出現(xiàn)類型轉(zhuǎn)化問(wèn)題,且在編譯階段不會(huì)報(bào)錯(cuò),到了運(yùn)行階段才暴露問(wèn)題,大大降低了程序的安全性和健壯性!

舉例之前說(shuō)一些轉(zhuǎn)型的分類:

向上轉(zhuǎn)型 用父類聲明一個(gè)子類對(duì)象 例如:Animal是Cat的父類,在聲明時(shí)我們這么寫:

  Animal cat = new Cat();

向下轉(zhuǎn)型

將父類對(duì)象強(qiáng)轉(zhuǎn)為其子類實(shí)例:

Animal cat = new Cat();
Cat anotherCat = (Cat) cat;

所以當(dāng)我們使用Object作為泛型來(lái)使用時(shí),不僅寫起來(lái)麻煩,還要不停的進(jìn)行類型轉(zhuǎn)化,還很容易出現(xiàn)問(wèn)題,很遜的誒~

舉個(gè)例子看看:

利用Object定義了一個(gè)數(shù)字變量,我們常識(shí)將其向下轉(zhuǎn)型為Integer和String。將一個(gè)數(shù)字轉(zhuǎn)型為字符串是一件荒唐的事情,可編譯器并不能察覺(jué)這件事,直到程序運(yùn)行了起來(lái)...

類型轉(zhuǎn)換異常?。?!

總結(jié)

泛型的出現(xiàn),當(dāng)類型轉(zhuǎn)化出現(xiàn)問(wèn)題的時(shí)候,在編譯階段就會(huì)暴露出來(lái)。解決了Object存在的諸多問(wèn)題,讓代碼更加優(yōu)雅,程序更加安全,更加健壯。

以上就是Java泛型T,E,K,V,N,?與Object區(qū)別和含義的詳細(xì)內(nèi)容,更多關(guān)于Java 泛型的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Java并發(fā)編程創(chuàng)建并運(yùn)行線程的方法對(duì)比

    Java并發(fā)編程創(chuàng)建并運(yùn)行線程的方法對(duì)比

    這篇文章主要為大家詳細(xì)介紹了Java并發(fā)編程創(chuàng)建并運(yùn)行線程的方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助
    2022-03-03
  • Java實(shí)現(xiàn)常見(jiàn)的排序算法的示例代碼

    Java實(shí)現(xiàn)常見(jiàn)的排序算法的示例代碼

    這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)常見(jiàn)的排序算法(選擇排序、插入排序、希爾排序等)的相關(guān)資料,文中的示例代碼講解詳細(xì),感興趣的可以了解一下
    2022-10-10
  • springboot項(xiàng)目如何設(shè)置時(shí)區(qū)

    springboot項(xiàng)目如何設(shè)置時(shí)區(qū)

    這篇文章主要介紹了springboot項(xiàng)目如何設(shè)置時(shí)區(qū)問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • Java利用Easyexcel導(dǎo)出excel表格的示例代碼

    Java利用Easyexcel導(dǎo)出excel表格的示例代碼

    這篇文章主要為大家詳細(xì)介紹了Java利用Easyexcel導(dǎo)出excel表格的示例代碼,文中的代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起了解一下
    2022-07-07
  • 詳細(xì)分析JVM類加載機(jī)制

    詳細(xì)分析JVM類加載機(jī)制

    JVM將class文件字節(jié)碼文件加載到內(nèi)存中,?并將這些靜態(tài)數(shù)據(jù)轉(zhuǎn)換成方法區(qū)中的運(yùn)行時(shí)數(shù)據(jù)結(jié)構(gòu),在堆(并不一定在堆中,HotSpot在方法區(qū)中)中生成一個(gè)代表這個(gè)類的java.lang.Class?對(duì)象,作為方法區(qū)類數(shù)據(jù)的訪問(wèn)入口,接下來(lái)將詳細(xì)講解JVM類加載機(jī)制
    2022-04-04
  • java 如何判斷是否是26個(gè)英文字母

    java 如何判斷是否是26個(gè)英文字母

    這篇文章主要介紹了java 如何判斷是否是26個(gè)英文字母的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2021-01-01
  • Java事務(wù)的個(gè)人理解小結(jié)

    Java事務(wù)的個(gè)人理解小結(jié)

    數(shù)據(jù)庫(kù)操作的事務(wù)習(xí)慣上就稱為Java事務(wù)
    2013-03-03
  • Java中StringBuilder與StringBuffer使用及源碼解讀

    Java中StringBuilder與StringBuffer使用及源碼解讀

    我們前面學(xué)習(xí)的String就屬于不可變字符串,因?yàn)槔碚撋弦粋€(gè)String字符串一旦定義好,其內(nèi)容就不可再被改變,但實(shí)際上,還有另一種可變字符串,包括StringBuilder和StringBuffer兩個(gè)類,那可變字符串有什么特點(diǎn),又怎么使用呢,接下來(lái)就請(qǐng)大家跟我一起來(lái)學(xué)習(xí)吧
    2023-05-05
  • 詳解Gradle安裝并配置到IDEA的方法

    詳解Gradle安裝并配置到IDEA的方法

    這篇文章主要介紹了Gradle安裝并配置到IDEA的方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-09-09
  • 解決springboot讀取application.properties中文亂碼問(wèn)題

    解決springboot讀取application.properties中文亂碼問(wèn)題

    初用properties,讀取java properties文件的時(shí)候如果value是中文,會(huì)出現(xiàn)亂碼的問(wèn)題,所以本文小編將給大家介紹如何解決springboot讀取application.properties中文亂碼問(wèn)題,需要的朋友可以參考下
    2023-11-11

最新評(píng)論