泛型,內部類

wah369發表於2020-11-17

對於泛型,不要求怎麼使用,要求看原始碼時能看懂就行。

泛型的意義:

1,自動進行型別的檢查

2,自動進行型別的轉換

泛型的一些重點

1,泛型時怎麼編譯的? 擦除機制--Object

2,泛型的型別 不參與型別的組成

3,泛型的引數不能是簡單型別

看一個簡單的泛型示例:

class MyArrayList<T> {
    
    public T[] elem;
    public int usedSize;

    public MyArrayList() {
        this.elem =(T[]) new Object[10];
    }
    public void push(T val) {
        this.elem[this.usedSize++] = val;
    }
    public T get() {
        return this.elem[0];
    }
}
public class TestDemo {
    public static void main(String[] args) {
        MyArrayList<Integer> myArrayList = new MyArrayList<>();
        myArrayList.push(1);
        myArrayList.push(2);
        int val = myArrayList.get();
        System.out.println(val);
        MyArrayList<String> myArrayList2 = new MyArrayList<>();
        System.out.println(myArrayList);
        System.out.println(myArrayList2);
    }

}

然後是泛型類的上界是什麼?寫成靜態方法怎麼寫

class GenericAlg <T extends Comparable> {
    //<T extends Comparable> 泛型的上界 , T實現了Comparable的介面
    //或者說Comparable實現了Comparable本身
    public  T maxValue(T[] array) {
        T max = array[0];
        for (int i = 0; i < array.length; i++) {
            if (array[i].compareTo(max) > 0) {
                max = array[i];
            }
        }
        return max;
    }
}
//靜態方法:
class GenericAlg2  {
    //<T extends Comparable> 泛型的上界 , T實現了Comparable的介面
    //或者說Comparable實現了Comparable本身
    public static<T extends Comparable<T>> T maxValue(T[] array) {
        T max = array[0];
        for (int i = 0; i < array.length; i++) {
            if (array[i].compareTo(max) > 0) {
                max = array[i];
            }
        }
        return max;
    }
}
public class TestDemo2 {

    public static void main(String[] args) {
        Integer[] array = {1,3,5,7,9};
        System.out.println(GenericAlg2.maxValue(array));
        System.out.println(GenericAlg2.<Integer>maxValue(array));
        //不寫Integer會根據實參型別判斷
    }

    public static void main1(String[] args) {
        Integer[] array = {5,2,4,9,7,6,3,8};
        GenericAlg<Integer> gla = new GenericAlg<>();
        System.out.println(gla.maxValue(array));

        GenericAlg2.maxValue(array);

    }
}

萬用字元:?   (通常出現在原始碼中)看差別 萬用字元:原始碼當中

 泛型的區別:

1,萬用字元一般用於讀取

 2,萬用字元不僅有上界 <? extends 上界>   還有下界     <? super 下界> 

class MyPrint<T> {
    public void printf(ArrayList<T> list) {
        for (T val : list) {
            System.out.print(val+" ");
        }
    }
}
class MyPrint2<T> {
    public void printf(ArrayList<?> list) {
        for (Object val : list) {
            System.out.print(val+" ");
        }
    }
}

邊界問題

只接受 Number 的子型別作為 E 的型別實參

沒有指定型別邊界 E,可以視為 E extends Object

public class MyArrayList<E extends Number> {
...
}
MyArrayList<Integer> l1; // 正常,因為 Integer 是 Number 的子型別
MyArrayList<String> l2; // 編譯錯誤,因為 String 不是 Number 的子型別

父子型別:

<>裡面的東西不參與型別的組成,雖然Object是Number的父類,但在泛型上就不是了

需要使用萬用字元來確定,<?>會被擦除為<Object>

public class MyArrayList<E> { ... }
// MyArrayList<Object> 不是 MyArrayList<Number> 的父型別
// MyArrayList<Number> 也不是 MyArrayList<Integer> 的父型別
// 需要使用萬用字元來確定父子型別
// MyArrayList<?> 是 MyArrayList<? extends Number> 的父型別
// MyArrayList<? extends Number> 是 MyArrayList<Integer> 的父型別

內部類:1,例項內部類 2,靜態內部類3,匿名內部類 4,本地內部類

1,例項內部類

例項資料成員是什麼?普通的成員屬性不加static

如何拿到一個例項內部類物件?

不能在例項內部類當中定義一個靜態變數,

class OuterClass {
    public int data1;
    private int data2;
    public static int data3;
    //例項內部類InnerClass
    class InnerClass {
        public int data4 = 4;
        //public static int data5 = 5;
        //不能在例項內部類當中定義一個靜態變數,
        //例項內部類相當於外部類的普通的成員變數
        public static final int data5 = 5;
        //被final修飾的常量在編譯時能夠確定的值
        public void test() {
            System.out.println(data4);
            System.out.println(data5);
        }
    }
}
//怎麼去拿到實力內部類的一個物件
public class TestDemo {
    public static void main(String[] args) {
        OuterClass outerClass = new OuterClass();
        //先new一下外部類,拿到外部類的一個引用,再通過外部類的引用new一個物件
        OuterClass.InnerClass innerClass = outerClass.new InnerClass();
        innerClass.test();
    }
}

2,靜態內部類

class OuterClass {
    public int data1 = 1;
    private int data2 = 2;
    public static int data3 = 3;


      //1.如何拿到一個靜態內部類的例項物件?
     // 2.靜態內部類當中是不可以訪問外部類的非靜態資料成員的,非要訪問呢
     

    static class InnerClass {
        //static靜態方法中不能有this
        public int data4 = 4;
        private int data5 = 5;
        public static int data6 = 6;

        //在構造內部類物件的時候直接傳過來外部類的引用
        OuterClass outerClass;
        public InnerClass(OuterClass out) {
            this.outerClass = out;
        }

        public void test() {
            System.out.println(outerClass.data1);
            System.out.println(outerClass.data2);
            System.out.println(data3);
            System.out.println(data4);
            System.out.println(data5);
            System.out.println(data6);
        }
    }
}

3.匿名內部類

class Outclass {
    public void test() {
        System.out.println("test()");
    }
}
public class TestDemo {

    public static void main(String[] args) {

        //匿名內部類
        new Outclass() {
            @Override
            public void test() {
                System.out.println("dsasffa");
            }
        }.test();
    }
}

4.本地內部類:沒人寫

class Outclass {
    public void test() {
        System.out.println("test()");
    }
}
public class TestDemo {

    public void func() {
        class A {
            //本地內部類
        }
    }
}

 

 

 

 

 

 

相關文章