2022-08-01 第六小组 张宁杰 泛型和枚举

目录

泛型
枚举

知识点

泛型:(Generics)

泛型广泛的、普通的类型,泛型能够帮助我们把【类型明确】的工作推迟到创建对象或者调方法的时候。换而言之,定义类的时候,我们不需要考虑这个数组到底要存什么类型。
但是创建这个对象的时候把里面要存的数据的类型确定下来。

泛型的修饰:

1.泛型类

泛型类把泛型定义在类上,用户在使用类的时候才能把类型给确定,具体的使用方法使用<>加上一个未知数,通常用T K V E等大写字母表示。

public static void main(String[] args) {
        // 如果一个泛型类,在创建对象的时候没有指定泛型类型
        // 默认还是Object
        // 在使用这个类的时候,去确定泛型类型
        // 现在这个超级数组就只能存String类型
        // 不规范
        SuperArray<String> superArray = new SuperArray();
        superArray.add("a");
//        superArray.add(1);
        // 这个超级数组superArray1就只能存Employee类型
        // 在JDK7以后,可以省略等号右边的泛型的声明,<>必须得写,规范
        // 类型推断
        SuperArray<Employee> superArray1 = new SuperArray<>();
        superArray1.add(new Employee());
        superArray1.add(new Employee());
        superArray1.add(new Employee());
        superArray1.add(new Employee());

        // 完整写法,JDK7以前
        SuperArray<Employee> superArray2 = new SuperArray<Employee>();

    }

2.泛型方法

如果只关心某个方法,可以不定义泛型类。
泛型方法是不是一定要在泛型类里?不是
泛型类里是不是一定要有泛型方法?不是
在定义泛型方法时,要首先定义泛型类型。定义在方法中间,泛型的使用处之前,使用泛型方法,最好要结合返回值,和Object一样。

public <T> T show(T t) {
        // 拿着这个t在方法中做好多事情,再把t返回回去
        // 调用另一个方法
        System.out.println(t);
        return t;
    }

    public static void main(String[] args) {
        new Ch03().show("哈哈");
    }

3.泛型接口

泛型类在继承时

1.父类是一个泛型类,子类要不要是泛型类?
2.永远记住,泛型的声明只能在当前类名后或者方法中间,而且声明的泛型是自己的。
3.在子类继承父类时,子类泛型和父类泛型都写出来的情况下,父跟子
4.如果在继承时,没有写出任何泛型,当前子类就不是泛型类。
如果在一个泛型类中,尽量就不要再使用泛型方法。泛型方法多数都是出现在非泛型类。

class Father<T> {

    T t;
}
// 在确定子类泛型的时刻,父类的泛型和子类一样
class Son<T> extends Father<T> {

}
//
class Son2 extends Father {

}
public class Ch04 {

    public static void main(String[] args) {
        Son<Employee> son = new Son<>();
        son.t = new Employee();
        Son2 son2 = new Son2();
        son2.t.notify();
    }
}

静态泛型方法

1.静态方法如果是泛型方法,泛型的声明必须写。
2.因为静态结构是属于类的,不属于某个对象。

interface Inter<T> {

    T show(T t);

    static <T> T info(T t){

        return t;
    }

}
class Demo01<T> implements Inter<T> {

//    @Override
//    public Object show(Object o) {
//        return null;
//    }

    @Override
    public T show(T t) {
        return t;
    }
}
public class Ch05 {

    public static void main(String[] args) {
        Inter.info(1);
    }
}

?通配符

可以接受任何类型。如果使用Object类型,就不写泛型。
泛型约束类的数据类型。
JDK1.5之后泛型。JDK5

class Animal {

}

class Dog extends Animal {

}

class Teddy extends Dog {
    public static void show(SuperArray<? super Teddy> superArray) {

    }
}

public class Ch06 {

    public static void main(String[] args) {

        SuperArray<Animal> superArray = new SuperArray<>();
//        superArray.add(new Animal());
//        superArray.add(new Dog());
//        superArray.add(new Teddy());
        Teddy.show(superArray);

    }
}

类型擦除

为了兼容性,使用原始类型(没有泛型)是可以的。
泛型刚刚出现的时候,还存在大量的不适用泛型的代码。
保证代码的兼容性,将参数化类型的实例传递给设计用于原始类型的方法必须是合法的。
为了保持兼容性,Java泛型中,其实有一种类似伪泛型,因为Java在编译期间,所有的泛型都会被擦掉。Java的泛型语法是在编译期这个维度上实现的。
正常来说在生成的字节码文件中,不包含泛型的类型信息的。
在JVM中看到的只是SuperArray,由泛型附加的类型信息对JVM是看不到的。 可以理解为,泛型的本质就是让程序员在编写代码时遵守的一个规则。比如SuperArray:在确定了泛型之后,这个超级数组中就统一只放同一类型的数据。如果放入其他类型,编译不通过。

使用泛型的注意事项

1.泛型不能是基本数据类型。(原则上来说,数组可以作为泛型,语法角度,不可以)<>里面放的就应该是类名。数组是在编译后才会生成一个类($xxxx)
2.方法重载:a.同一个类里 b.方法名相同 c.参数不同
原理:类型擦除。
3.多态上。

 public static void show(SuperArray<Employee> superArray){

    }
    public static void main(String[] args) {
        SuperArray<Object> superArray = new SuperArray<>();
        superArray.add(10);
    }

枚举类型

应用场景

在某些情况下,一个类的对象的个数是有限的,如季节,春夏秋冬,比如24节气,星期。
规定这个类的对象的个数。枚举在switch中使用,JDK1.5之后,枚举类的命名规则:所有的枚举类要以Enum结尾。
枚举类中:
把需要用到的对象声明出来
写对应的构造器
可以有set,get方法

使用枚举类实现单例模式

单元素的枚举类型已经成为实现单例模式的最佳方案。

class Singleton {

    // 私有化构造器
    private Singleton() {}

    // 提供公有的获取实例的静态方法
    public static Singleton getInstance(){
        return SingletonHolder.INSTANT.instant;
    }

    // 声明一个枚举类(内部类)
    private enum SingletonHolder{

        INSTANT;

        private final Singleton instant;

        SingletonHolder() {
            instant = new Singleton();
        }
    }
}

public class Ch05 {

    public static void main(String[] args) {
        System.out.println(Singleton.getInstance() == Singleton.getInstance());
    }
}

枚举的优势

1.int类型不具备安全性。假如某个程序员在定义int时少写了个final,会存在被他人修改的风险。枚举类,它天然就是一个常量类
2.使用int类型,语义不够明确。如果说在控制台打印输入1。

public static void main(String[] args) {
//        Integer seasonStr = 1;
//        if(seasonStr == SeasonConstant.SPRING) {
//            System.out.println(1);
//        }
        // 枚举里面都是常量,静态
        // 推荐枚举的比较使用 ==
        SeasonEnum spring = SeasonEnum.SPRING;
        String name = "春天";
        SeasonEnum1 spring1 = SeasonEnum1.SPRING;
//        if(name.equals(spring.getName())){
//            System.out.println("春天");
//        }
        if(spring1.equals(spring)) {
            System.out.println(123);
        }
    }

开发经验

开发中,能够在业务上解决的问题,尽量不要在技术上解决。

posted @ 2022-08-01 21:55  贵妃就是贵妃  阅读(14)  评论(0编辑  收藏  举报