枚举、泛型、通配符

枚举

一、枚举的入门

枚举就是一个受限制的类,默认继承 Enum
枚举的第一行必须定义该枚举类型的对象
枚举类型对象默认添加: public static final 类型
枚举没有继承明确类(自定义枚举类默认继承Enum,Enum默认继承Object)
枚举类不能被继承
枚举里可以有构造方法、成员方法、静态方法、抽象方法
枚举可以实现接口

二、枚举的构造器

  • 枚举的关键字:enum ,使用逗号隔开
  • 枚举可以配合switch使用
  • 枚举可以有构造函数
  • package com.xinzhi;
    public enum Color {
        RED,GREEN,BLUE,YELLOW;
         * 有参构造
        private String num;
        Color(String num){
            this.num = num;
        public String getNum() {
            return num;
         * 无参构造
        Color(){
            System.out.println ("这是枚举!");
        public String getMsg() {
            return num;
        public void aa(){
            System.out.println (this.name () + "被打印了");
    
    package com.xinzhi;
    public class Color2 {
         * final静态常量
        public static final int RED = 1;
        public static final int BLUE = 2;
        public static final int YELLOW = 3;
        public static final int GREEN = 4;
    
    package com.xinzhi;
    import static com.xinzhi.Color2.BLUE;
    import static com.xinzhi.Color2.RED;
    public class Test {
        public static void main(String[] args) {
            Color c = Color.RED;
            c.aa ();
            int color = Color2.RED;
            test (color);
            private static void test(int c){
                switch (c){
                    case RED:
                        System.out.println ("这是红色!");
                        break;
                    case BLUE:
                        System.out.println ("这是蓝色!");
                        break;
                    default:
                        System.out.println ("这不是红或蓝");
                        break;
             * 抽离方法Ctrl+Alt+M
            private static void test(Color c){
                switch (c){
                    case RED:
                        System.out.println ("这是红色!");
                        break;
                    case BLUE:
                        System.out.println ("这是蓝色!");
                        break;
                    default:
                        System.out.println ("这不是红或蓝");
    

    三、泛型入门

    泛型设计原则:

    只要在编译时期没有出现警告,那么运行时期就不会出现ClassCastException异常。

    把类型明确的工作推迟到创建对象或调用方法的时候才去明确的特殊类型。

    参数化类型:

  • 把类型当做参数一样传递
  • <数据类型>只能用引用类型
  • 相关术语:

  • ArrayList<E>中的E成为类型参数变量
  • ArrayList<Interget>中的Integer称为实际类型参数
  • 整个称为ArrayList<E>泛型类型
  • 整个ArrayList<Inte>称为参数化的类型ParameterizedType
  • 为什末需要泛型:

  • 代码更加简洁,【不用强制转换】
  • 只要编译时期警告,那么运行时期就不会出现ClasCastExce异常
  • 可读性和稳定性【在编写集合的时候,就限定了类型】
  • **有了泛型后使用增强****for遍历集合****

    四、泛型类、泛型接口

    4.1泛型类

    泛型类就是把泛型类定义在类上,用户使用该类的时候,才把类型明确类型

    在类上定义的泛型,在类的方法中也可以使用

    定义泛型方法泛型是先定义后使用

    4.2泛型方法

    在类上定义的泛型,在方法中也可以使用

    定义泛型方法(泛型是先定义后使用)

    //定义泛型的方法
    public <T> void show(T t){
        System.out.println(t);
    

    用户传进来的是什么类型,返回值就是什么类型

    public static void main(String[] args){
        //创建对象
        ObjecyTool tool = new ObjectTool();
        //调用方法,传入的参数是什么类型,返回值就是什么类型
        tool.show("hello")
    

    4.3泛型类派生出的子类

    继承分为两种情况:

  • 子类明确泛型类的类型参数变量;
  • *把泛型定义在接口上 public interface Inter<T>{ public abstract void show(T t);

    实现泛型接口的类

    *子类明确泛型类的类型参数变量 public class InterImpl implements Inter<String>{ @Override public void show(String s){ System.out.println(s);
    子类不明确泛型类的类型参数变量;

    当子类不明确泛型类的类型参数变量时,外界使用子类的时候,也需要传递类型参数变量进来,在实现类上需要定义出类型参数变量

    *子类不明确泛型类的类型参数变量 *实现类也要定义出<T>类型的 public class InterImpl<T> implements Inter<String>{ @Override public void show(T t){ System.out.println(t);
    public class InterImpl<T> implements Inter<String>{
        //测试第一种情况
        //Inter<String> i = new Interimpl();
        //i.show("hello");
        //测试第二种情况
        Inter<String> ii = new Interimpl();
        i.show("100");
    

    实现类的重要是重写父类的方法, 返回值的类型是要和父类一样的!

    类上声明的泛型只对非静态成员有效

    4.4类型通配符

    设定通配字符上限
    List<? extends Number>
    

    List集合装载的元素只能是Number的子类或自身

    设定通配符下限
    //传递进来的只能是Type或Type的父类
    <? super Type>
    

    五、通配符和泛型方法

    设置通配符的上限
    List<? extends Number>
    

    List集合装载的元素只能是Number的子类或自身

    设置通配符的下限
    //传递进来的只能是Type或Type的父类
    <? super Type>
    //使用通配符
    public static void test (List<?> list){
    //使用泛型方法
    public <T> void test2 (List<T> t){
    

    在泛型的上限和下限中有一个原则:PECS(Producer Extends ConsumerSuper)

  • 带有子类限定的可以从泛型读取【(?extend T)】 Producer Extends
  • 带有超类限定的可以从泛型读取【(?super T)】 Consumer Super
  • Extends

    5.2泛型擦除

    泛型是提供给javac编译器使用的,用于限定集合的输入类型,让编译器在源代码级别上,即挡住向集合中插入非法数据。但编译器编译完带有泛型的java程序后,生成的class文件中将不在带有泛型信息,史此程序效率不受到影响

    当把带有泛型特性的集合赋值给老版本的集合时候,会把泛型给擦出了。

    保留的就类型参数的上限

    List<String> list = new ArraayList<>();
    //类型被擦出了,保留的是类型的上限,String的上限就是Object
    List list = list;