总结java的泛型和内部类

泛型与内部类

  • 泛型
  • 内部类
    • 实例内部类
    • 静态内部类
    • 匿名内部类
    • 本地内部类

泛型

泛型是java1.5中增加的一个新特性,通过泛型可以写与类型无关的代码,即编写的代码可以被很多不同类型的对象所重用,经常用在一些通用的代码实现中,比如:java集合框架中的类几乎都是用泛型实现的。

泛型的本质是:类型参数化。类似函数传参一样,传递不同的实参,函数运行完将会产生不同的结果。

泛型12点总结

  1. class MyStack< T> 此时< T>代表是一个占位符,表示当前类是一个泛型类
  2. this.elem = new T[10]; 不能实例化泛型类型的数组对象
  3. Mystack< Integer> myStack = new MyStack<>();
    MyStack< Integer> 这里指定当前类可以存放的数据类型
    new MyStack<>() 与前面匹配
  4. 泛型的意义:
    a:可以自动进行类型的检查
    b:可以自动进行类型的转换
  5. MyStack< int> myStack = new MyStack<>();
    简单类型 不能作为泛型类型的参数 包装类型->引用类型
  6. 泛型到底是怎么编译的? 擦除机制
    擦除为Object的意义 就是可以放任意类型的数据
    运行java程序的时候,是没有泛型的概念的
  7. MyStack< Integer> stack : 泛型类型的参数,不参与类型的组成
  8. 泛型的上界:
    class Algorithm > {}
    T:T类型一定要实现Comparable接口
    class Algorithm< E extends Animal> {}
    E:可以是Animal的子类,或者是Animal自己类本身
  9. 泛型没有下界
  10. 泛型方法:
    public static< T> T findMaxVal(T[] array) {}
    public static> T findMaxVal(T[] array) {}
  11. 通配符:通配符实际上也是一种泛型。一般在源码中居多一点
    泛型一般用于读取和写入,而通配符一般用于读取
    public static< T> void print(ArrayList< T> list) {}
    public static void print(ArrayList list) {}
    通配符上界: 表示传入的参数 ? 是上界 E 的子类或者 E 自己本身
    通配符下界: 表示传入的参数 ? 是下界 E 的父类或者 E自己本身
  12. ArrayList< Integer> list ArrayList< Number> list
    他们不会构成父子类关系,因为类型擦除机制 以及 不参与类型的组成


class MyStack<T> {
    public T[] elem;
    public int top;
    public MyStack() {
        this.elem = (T[])new Object[10];
        //this.elem = new T[10];
    }
    public void push(T val) {
        this.elem[top] = val;
        top++;
    }
    public T getTop() {
        return this.elem[top-1];
    }
}

/**
 * 写一个泛型类,找到数组当中的最大值
 */
class Algorithm<T extends Comparable<T> > {
    public T findMaxVal(T[] array) {
        T max = array[0];
        for (int i = 1; i < array.length; i++) {
            if(array[i].compareTo(max) >= 0) {
                max = array[i];
            }
        }
        return max;
    }
}

class Person {

}
/**
 * 泛型方法
 */
class Algorithm2 {
    public static<T extends Comparable<T>> T findMaxVal(T[] array) {
        T max = array[0];
        for (int i = 1; i < array.length; i++) {
            if(array[i].compareTo(max) >= 0) {
                max = array[i];
            }
        }
        return max;
    }
}

/**
 *写一个方法 打印一个list当中的所有的数据
 */
class Test {
    public static<T> void print2(ArrayList<T> list) {
        for (T x:list) {
            System.out.println(x);
        }
    }

    public static void print(ArrayList<?> list) {
        for (Object x:list) {
            System.out.println(x);
        }
    }
}

public class TestDemo {

    public static void main(String[] args) {
        //Integer extends Number
        ArrayList<Integer> list = new ArrayList<>();
        ArrayList<Number> list2 = new ArrayList<>();
        list2.addAll(list);
    }

    public static void main5(String[] args) {
        ArrayList<Integer> list1 = new ArrayList<>();
        list1.add(1);
        list1.add(2);
        list1.add(3);
        Test.print(list1);

        ArrayList<Double> list2 = new ArrayList<>();
        list2.add(1.0);
        list2.add(2.0);
        list2.add(3.0);
        Test.print(list2);
    }

    public static void main4(String[] args) {
        Integer[] array = {1,2,3,4,5,6,7};
        System.out.println(Algorithm2.<Integer>findMaxVal(array));
        System.out.println(Algorithm2.findMaxVal(array));
    }

    public static void main3(String[] args) {
        Algorithm<Integer> algorithm = new Algorithm<>();
        Integer[] array = {1,2,3,4,5,6,7};
        System.out.println(algorithm.findMaxVal(array));

        //Algorithm algorithm2 = new Algorithm<>();
    }

    public static void main2(String[] args) {
        MyStack<Integer> myStack = new MyStack<>();
        System.out.println(myStack);
    }

    public static void main1(String[] args) {
       /* Stack stack1 = new Stack<>();
        Stack stack2 = new Stack<>();
        Stack stack3 = new Stack<>();*/
        MyStack<Integer> myStack = new MyStack<>();
        myStack.push(1);
        myStack.push(19);
        myStack.push(80);
        int a = myStack.getTop();
        System.out.println(a);

        MyStack<String> myStack2 = new MyStack<>();
        myStack2.push("hello");

        //假设不指定泛型的类型参数
        @SuppressWarnings("unchecked")
        MyStack<String> myStack3 = new MyStack();
        myStack3.push("fsafsasa");
    }
}

内部类

实例内部类

实例内部类: 定义在类的内部的一个类。

  1. 如何实例化内部类对象?
    OuterClass.InnerClass innerClass2 = out.new InnerClass();
    外部类名.内部类名 变量 = 外部类对象的引用.new 内部类();

  2. 只要是内部类,那么生成的字节码文件格式:外部类$内部类.class

  3. 在实例内部类当中,不能定义静态的成员变量!!
    如果非要定义,那么一定要是在编译时期确定的值 public static final

  4. this实际上是一个静态的成员
    System.out.println(OuterClass.this.data1);

  5. 实例内部类实际上拥有2个this。一个是实例内部类自己的,一个是外部类的
    所以这里有个面试题:同学,实例内部类,是否有额外的内存开销? 有

public class OuterClass {
    public int data1 = 1;
    public static int data2 = 2;
    class InnerClass {
        public int data3 = 3;
        public int data1 = 11;
        public static final int data4 = 4;
        public InnerClass() {
        }
        public void test() {
            System.out.println("InnerClass::test()");
            System.out.println(data3);
            System.out.println(data4);
            System.out.println(this.data1);
            System.out.println(OuterClass.this.data1);
        }
    }
}

public class Test1 {
    //实例内部类
    public static void main(String[] args) {
        //InnerClass innerClass = new InnerClass();
        OuterClass out = new OuterClass();
        OuterClass.InnerClass innerClass2 = out.new InnerClass();
        innerClass2.test();
    }

}

静态内部类

静态内部类:定义在类的内部的一个类。但是由static来修饰的.

  1. 静态内部类对象如何拿到?
    OuterClass.InnerClass innerClass = new OuterClass.InnerClass();
    = new 外部类.静态内部类();
  2. 字节码文件和上面试一样的
  3. 在静态内部类当中,是不可以访问外部类的非静态数据成员的!!!!
    因为,外部类的非静态数据成员 是依赖于外部类对象的
    但是:如果非让你访问呢?????
    思路:能不能给个外部类对象的引用???
class OuterClass {
    public int data1 = 1;
    public static int data2 = 2;
    //静态内部类
    static class InnerClass {
        public int data3 = 3;
        public static int data4 = 4;
        public OuterClass out;
        public InnerClass(OuterClass out) {
            this.out = out;
        }
        public void test() {
            System.out.println("InnerClass::test()");
            //System.out.println(OuterClass.this.data1);不对的
            System.out.println(out.data1);
            System.out.println(data2);
            System.out.println(data3);
            System.out.println(data4);
        }
    }
}

public class Test2 {
    public static void main(String[] args) {
        OuterClass out = new OuterClass();
        OuterClass.InnerClass innerClass = new OuterClass.InnerClass(out);
        innerClass.test();
    }
}

匿名内部类

匿名内部类:
在匿名内部类当中,使用的变量,或者是常量 或者是在整个过程当中 没有发生改变的量

//匿名内部类
class OuterClass {

    public void sayHello() {
        System.out.println("hello");
    }

}

public class Test3{
    public static void main(String[] args) {
        int data1 = 10;
        new OuterClass(){
            @Override
            public void sayHello() {
                //data1 = 10;
                //super.sayHello();
                System.out.println("hhhhhh,匿内部类终于学完了!!!");
                System.out.println(data1);
            }
        }.sayHello();

    }
}

本地内部类

本地内部类:方法里面定义的类 没有意义。

    public void func() {
        class  A {
            //本地内部类
        }
    }

你可能感兴趣的:(数据结构,javaSE,java,泛型,内部类,javase,数据结构)