最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java開發(fā)崗位面試被問到泛型怎么辦

 更新時間:2021年07月17日 14:55:15   作者:蛋撻學姐  
泛型在java中有很重要的地位,在面向?qū)ο缶幊碳案鞣N設計模式中有非常廣泛的應用。java泛型知識點也是Java開發(fā)崗位必問的一個話題,今天小編就給大家普及下Java泛型常見面試題,感興趣的朋友一起看看吧

1、泛型的基礎概念

1.1 為什么需要泛型

        List list = new ArrayList();//默認類型是Object
        list.add("A123");
        list.add("B234");
        list.add("C345");
        System.out.println(list);
        for(int i=0;i<list.size();i++){
            //若要將list中的元素賦給String變量,需要進行類型轉(zhuǎn)換,不然會報Incompatible types錯誤,顯示list.get(i)返回的是Object
            String str =  (String) list.get(i);
            System.out.println(str);
        } 
        list.add(123);//因為類型是Object,我們可以把Integer類型或者其他數(shù)據(jù)類型的元素也加入list之中
        System.out.println(list.get(3));
​
        for(int i=0;i<list.size();i++){
            //String str =  (String) list.get(i);//但是在這里會報錯java.lang.ClassCastException,我們不能直接將Integer類型的數(shù)據(jù)轉(zhuǎn)換成String
            System.out.println(list.get(i).getClass());
        }

如代碼中所示,當我們定義了一個List,list默認的類型是所有對象的基類Object,那么我們?nèi)〕鰯?shù)據(jù)的時候需要經(jīng)過一次類型轉(zhuǎn)換才能進行對象的實際類型的相關操作。因為List中的類型是Object,那么我們先添加了String類型的數(shù)據(jù),然后再添加Integer或者其他類型的數(shù)據(jù)也是允許的,因為編譯時List中是Object類型的數(shù)據(jù),然而運行的時候卻是它本身的類型,所以當我們將List中的數(shù)據(jù)當作String處理時會拋出java.lang.ClassCastException。

那么有沒有什么辦法可以使集合能夠記住集合內(nèi)元素各類型,且能夠達到只要編譯時不出現(xiàn)問題,運行時就不會出現(xiàn)java.lang.ClassCastException異常呢?答案就是使用泛型。

1.2 什么是泛型

Java泛型設計原則是:只要在編譯時期沒有出現(xiàn)警告,那么運行時期就不會出現(xiàn)ClassCastException異常。

泛型,即“參數(shù)化類型”,把類型明確的工作推遲到創(chuàng)建對象或調(diào)用方法的時候才去明確的特殊類型,把<數(shù)據(jù)類型>當作是參數(shù)一樣傳遞。

相關術(shù)語:

  • ArrayList中的E稱為類型參數(shù)變量
  • ArrayList中的Integer稱為實際類型參數(shù)
  • 整個稱為ArrayList泛型類型
  • 整個ArrayList稱為參數(shù)化的類型ParameterizedType

泛型的作用:

代碼更加簡潔【不用強制轉(zhuǎn)換】

程序更加健壯【只要編譯時期沒有警告,那么運行時就不會拋出ClassCastException的異?!?/p>

可讀性和穩(wěn)定性【在編寫集合的時候,就限定了類型】

        List<String> strlist = new ArrayList<String>();
        List<Integer> intlist = new ArrayList<Integer>();​
        strlist.add("A");
        strlist.add("B");
        //strlist.add(123);//編譯時報錯​
        for(String str:strlist){
            System.out.println(str);
            //A
            //B
        }
​//加入Java開發(fā)交流君樣:756584822一起吹水聊天
        System.out.println(strlist.getClass());//class java.util.ArrayList
        System.out.println(intlist.getClass());//class java.util.ArrayList
        System.out.println(strlist.getClass()==intlist.getClass());//true

泛型擦除

泛型是提供給javac編譯器使用的,它用于限定集合的輸入類型,讓編譯器在源代碼級別上,即擋住向集合中插入非法數(shù)據(jù)。但編譯器編譯完帶有泛型的java程序后生成的class文件中將不再帶有泛型信息,以此使程序的運行效率不受到影響,這個過程稱之為“擦除”。

泛型這個概念是JDK5提出的,JDK5以前的版本是沒有泛型的,需要建通JDK5以下的集合。當把帶有泛型特性的集合賦值給老版本的集合的時候,會把泛型給擦除了,它保留的是類型參數(shù)的上限,即Object。而當我們將沒有類型參數(shù)的集合賦給帶類型參數(shù)的集合,也不會報錯,僅僅是會提示“未經(jīng)檢查的轉(zhuǎn)換(Unchecked assignment)”,甚至也可以將它賦給其他不同類型的帶有泛型特性的集合,只是依舊會拋出ClassCastException異常。

        //類型被擦除了,保留的是類型的上限,String的上限就是Object
        List list = strlist;
​
        List<String> stringList2 = list;
        List<Integer> intList2 = list;//你也可以把它賦給Integer類型的集合,但是當你把這個集合當成Integer的集合操作的時候,依舊會拋出ClassCastException異常
​
        for (Integer i:intList2){//java.lang.ClassCastException
            System.out.println(i);
        }

2、泛型的定義和使用

2.1 泛型類\泛型接口

泛型類、泛型接口就是把泛型定義在類或者接口上,在用戶使用該類的時候才把類型明確下來。我們常用的集合,List,Map<K,V>,Stack……就是泛型類。在類上定義的泛型,在泛型類的方法、變量中都可以使用。

由于類型參數(shù)變量T在java泛型中僅僅是一個占位符,在傳遞參數(shù)之后才能使用,即在完成實例創(chuàng)建之后才能使用,所以在泛型類中,不能定義包含泛型類型的靜態(tài)變量和靜態(tài)方法,會報錯cannot be referenced from a static context。泛型類中包含泛型類型的變量和方法必須在創(chuàng)建了實例明確了傳遞的類型參數(shù)后才可以使用。

class Myset<T>{
    private T value;
    //public static T sval;//cannot be referenced from a static context
    public static int sval2;
​//加入Java開發(fā)交流君樣:756584822一起吹水聊天
    public Myset(){​
    }​
    public Myset(T val){
        this.value = val;
    }​
    public void setValue(T value) {
        this.value = value;
    }​
    public T getValue() {
        return value;
    }​
   /* public static T getSval(){//cannot be referenced from a static context
        return sval;
    }*/
}
       Myset<String> myset = new Myset<>();
       myset.setValue("12345");
       System.out.println(myset.getValue());//12345​
       myset = new Myset<>("23");
​//加入Java開發(fā)交流君樣:756584822一起吹水聊天
       System.out.println(myset.getClass());//class liwx.learning.Myset

2.2 泛型方法

 public static  <T> void PrintArray(T [] arr){
        System.out.print("[");
        for(T t:arr){
            System.out.print(t+",");
        }
        System.out.println("]");
    }
Integer[]  a = {1,2,3,4,5,6,7};
PrintArray(a);//[1,2,3,4,5,6,7,]

2.3 泛型類的繼承

泛型類的子類有兩種繼承方式

  • 子類不明確泛型類的參數(shù)變量,子類也是泛型類
  • 子類明確泛型類的參數(shù)變量,子類不是泛型類
//子類不明確泛型類的參數(shù)變量,子類也是泛型類
class MyChiSet1<T> extends Myset<T>{
    public MyChiSet1(){​
    }
    public MyChiSet1(T val){
        super(val);
    }
​//加入Java開發(fā)交流君樣:756584822一起吹水聊天
}
//子類明確泛型類的參數(shù)變量,子類不是泛型類
class MyChiSet2 extends Myset<String>{
    public MyChiSet2(){​
    }
    public MyChiSet2(String val){
        super(val);
    }
}

2.4 類型通配符?及其上下限

通配符<?>和類型參數(shù)變量的區(qū)別是什么?通配符<?>是實參而不是類型形參,而且List<?>在邏輯上是List,List等所有List<具體類型實參>的父類,它的使用比類型形參T更加靈活,但傳入的通配符通常進行的是許多于具體類型無關的操作,如果涉及到具體類型相關的操作,以及返回值,還是需要使用泛型方法T。

當我們使用?號通配符的時候,只能調(diào)用與對象無關的方法,不能調(diào)用對象與類型有關的方法。因為直到外界使用才知道具體的類型是什么。

//雖然Object是所有類的基類,但是List<Object>在邏輯上與List<Integer>等并沒有繼承關系,這個方法只能傳入List<Object>類型的數(shù)據(jù) 
   public static void showOList(List<Object> list){
        System.out.println(list.size());
    }
    //同理,這個方法只能傳入List<Number>類型的數(shù)據(jù),并不能傳入List<Integer>
    public static void showList(List<Number> list){
        System.out.println(list.size());
    }//加入Java開發(fā)交流君樣:756584822一起吹水聊天
    //使用通配符,List<?>在邏輯上是所有List<Number>,List<Integer>,List<String>……的父類,可以傳遞所有List類型的數(shù)據(jù),但是不能在List<?>類型的數(shù)據(jù)進行于具體類型相關的操作,如add
    public static void showList2(List<?> list){
        System.out.println("<?>");
        System.out.println(list.size());
    }
    //設置通配符上限,可以傳入List<Number及Number的子類>
    public static void showNumList(List<? extends Number> list){
        System.out.println(list.size());
    }
   //設置通配符上限,List<? super Number>只可以傳入List<Number及其父類>
    public static boolean Compare(List<? super Number> list1,List<? super Integer> list2){
        return list1.size()>list2.size();
    }
     List<Integer> Intgetlist = new ArrayList<>();
        List<Number> Numberlist = new ArrayList<>();
        //雖然Number是Integet的父類,但是傳入List,它們邏輯上沒有了繼承關系
        System.out.println(Intgetlist.getClass()==Numberlist.getClass());//true
​//加入Java開發(fā)交流君樣:756584822一起吹水聊天
        //showList(java.util.List<java.lang.Number>)
        //List<Integer>和List<Number>邏輯上無繼承關系,所以無法調(diào)用
        //showList(Intgetlist);//showList(java.util.List<java.lang.Number>)in FXtest cannot be applied to(java.util.List<java.lang.Integer>)
        showList(Numberlist);​
       //public static void showList2(List<?> list)
        //通配符List<?>在邏輯上是所有List<具體參數(shù)類型>的父類,方法可以傳入其子類類型的數(shù)據(jù)
        showList2(Intgetlist);
        showList2(Numberlist);​
        // public static void showNumList(List<? extends Number> list)
        //當設定了通配符上限,只能傳入List<Number及其子類>的數(shù)據(jù)
        List<String> Stringlist = new ArrayList<>();
        showNumList(Intgetlist);
        showNumList(Numberlist);//加入Java開發(fā)交流君樣:756584822一起吹水聊天
        //showNumList(Stringlist);//showNumList(java.util.List<? extends java.lang.Number>)in FXtest cannot be applied to(java.util.List<java.lang.String>)​
        //public static boolean Compare(List<? super Number> list1,List<? super Integer> list2)
        //當設定了通配符下限,List<? super Number>只能傳入List<Number及其父類>的數(shù)據(jù),不能傳入子類Integer的List,
        // 而List<? super Integer>則可以傳入其父類Number的List
        //Compare(Intgetlist,Numberlist);
        Compare(Numberlist,Intgetlist);

通配符的使用在邏輯上還原了泛型類傳入數(shù)據(jù)類型的參數(shù)父類子類的繼承關系,同時也可以按照需求設定通配符的上限了下限。

  • List<?>在邏輯上是所有List<具體參數(shù)類型>的父類,可對所有List數(shù)據(jù)進行操作
  • List<? extends Type>設定了通配符的上限,可對所有Type及Type的子類進行操作
  • List<? super Type>設定了通配符的下限,可對所有Type及Type的父類進行操作

總結(jié)

本篇文章就到這里了,希望能給你帶來幫助,也希望您能夠多多關注腳本之家的更多內(nèi)容!

相關文章

  • java定時任務框架elasticjob詳解

    java定時任務框架elasticjob詳解

    這篇文章主要介紹了java定時任務框架elasticjob詳解,Elastic-Job是ddframe中dd-job的作業(yè)模塊中分離出來的分布式彈性作業(yè)框架。該項目基于成熟的開源產(chǎn)品Quartz和Zookeeper及其客戶端Curator進行二次開發(fā)。,需要的朋友可以參考下
    2019-06-06
  • 淺談Java模板引擎性能對比

    淺談Java模板引擎性能對比

    本篇文章主要介紹了淺談Java模板引擎性能對比 ,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-09-09
  • EL表達式簡介_動力節(jié)點Java學院整理

    EL表達式簡介_動力節(jié)點Java學院整理

    EL全名為Expression Language,這篇文章主要給大家介紹EL表達式的主要作用及內(nèi)容簡介,感興趣的朋友一起看看
    2017-07-07
  • 解決idea中debug工具欄消失后如何顯示的問題

    解決idea中debug工具欄消失后如何顯示的問題

    這篇文章主要介紹了解決idea中debug工具欄消失后如何顯示的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-02-02
  • Spring?Boot各類變量的使用小結(jié)

    Spring?Boot各類變量的使用小結(jié)

    這篇文章主要介紹了Spring?Boot各類變量的使用小結(jié),本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友參考下吧
    2024-01-01
  • 初識Java基礎之數(shù)據(jù)類型與運算符

    初識Java基礎之數(shù)據(jù)類型與運算符

    Java是一種強類型語言,每個變量都必須聲明其數(shù)據(jù)類型,下面這篇文章主要給大家介紹了關于Java基礎之數(shù)據(jù)類型與運算符的相關資料,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考下
    2021-10-10
  • ssm實現(xiàn)分頁查詢的實例

    ssm實現(xiàn)分頁查詢的實例

    下面小編就為大家?guī)硪黄猻sm實現(xiàn)分頁查詢的實例。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-11-11
  • Spring Aop組成部分及實現(xiàn)步驟

    Spring Aop組成部分及實現(xiàn)步驟

    面向切面編程,是對面向?qū)ο缶幊痰囊环N補充,是一種編程思想,是對某一類的事情的集中處理,這篇文章主要介紹了Spring Aop組成部分及實現(xiàn)步驟,需要的朋友可以參考下
    2023-08-08
  • IntelliJ IDEA 2020.1.2激活工具下載及破解方法免費可用至2089年(強烈推薦)

    IntelliJ IDEA 2020.1.2激活工具下載及破解方法免費可用至2089年(強烈推薦)

    這篇文章主要介紹了IntelliJ IDEA 2020.1.2激活工具下載及破解方法免費可用至2089年(強烈推薦),本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-09-09
  • Java老手該當心的13個錯誤

    Java老手該當心的13個錯誤

    這篇文章主要介紹了Java老手該當心的13個錯誤,需要的朋友可以參考下
    2015-04-04

最新評論

青阳县| 含山县| 枣阳市| 宜兰县| 通州区| 郧西县| 保康县| 边坝县| 获嘉县| 和政县| 江门市| 临漳县| 辽宁省| 嘉荫县| 榆树市| 通榆县| 如东县| 铜陵市| 武冈市| 房产| 炎陵县| 东城区| 台州市| 油尖旺区| 新丰县| 正安县| 密云县| 重庆市| 乌拉特中旗| 泸州市| 竹溪县| 吕梁市| 铜川市| 芦溪县| 万荣县| 白山市| 岚皋县| 比如县| 九江县| 泾阳县| 宜城市|