其他分享
首页 > 其他分享> > 20220801 第五小组 罗大禹 学习笔记

20220801 第五小组 罗大禹 学习笔记

作者:互联网

20220801 第五小组 罗大禹 学习笔记

Java 泛型及枚举

学习重点

1.泛型
2.枚举

学习心得

今天老师讲的内容回去还是得好好吸收下,感觉上课听的并不是很明白

学习内容

Java 泛型及枚举

JavaSE高级部分

  1. 泛型
  2. 枚举
  3. .多线程 前3年(难)
  4. 集合(数据结构,树,二叉树,红黑树,B+树,B-树)
  5. IO流(文件)
  6. 反射和注解
  7. 网络通信Socket(tomcat)

泛型:(Generics)

之前写的超级数组中要么只能存数字,要么什么都能存,有一些鸡肋。

利用泛型可以解决这个问题。

泛型(了解)

什么是泛型?

​ 泛型:广泛的、普通的类型。

​ 泛型能够帮助我们把【类型明确】的工作推迟到创建对象或者调方法的时候。

​ 通俗的讲:定义类的时候,不需要考虑这个数组到底要存什么类型。创建这个超级数组对象的时候把里面要存的数据的类型确定下来。

泛型的应用场景:
  1. 父类(接口),起到的是一个规范的作用,对里面的数据类型没有明确要求。

  2. 容器类。(超级数组,链表,队列,栈)

    当类型无法确定时,使用泛型。

    开发中,我们更多的是会使用到一些泛型类或泛型接口。

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

​ 泛型类把泛型定义在类上,用户在使用类的时候才能把类型给确定。

​ 具体的使用方法使用<>加上一个未知数。通常用T K V E等大写字母表示。

​ 实际上用什么都可以,只要是个单词就可以。

举例说明:

public class Ch02 {

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

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

    }
}
泛型方法:

​ 我们如果只关心某个方法,可以不定义泛型类,只定义泛型方法。

​ 在定义泛型方法时,要首先定义泛型类型。

位置:

​ 定义在方法中间,泛型的使用处之前

​ 使用泛型方法,最好要结合返回值,和Object一样。

注意:

举例说明:

public class Ch03 {

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

    public static void main(String[] args) {
        System.out.println(new Ch03().show("哈哈"));
    }
}
泛型类继承关系:

泛型类在继承时:

  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) {
        // T声明为Employee类型,t为Employee类型
        Son<Employee> son = new Son<>();        
        son.t = new Employee();
        // T未声明,t为Object类型
        Son2 son2 = new Son2();
        son2.t.toString();
    }
}
泛型接口:

​ 如果在一个泛型类中,尽量就不要再使用泛型方法。

​ 泛型方法多数都是出现在非泛型类。

静态泛型方法:

  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 T show(T t) {
        return t;
    }
}
public class Ch05 {

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

可以接受任何类型。

如果使用Object类型,就不要写泛型。

泛型使用来约束类的数据类型。

JDK1.5之后泛型。JDK5

<? extends Animal>定义上限,内容为Animal及其子类

<?  super Teddy>定义下限,内容为Teddy及其父类

举例说明:


// 父类(外部类)
class Animal {

}

// 子类(外部类)
class Dog extends Animal {

}

// 子类(外部类)
class Teddy extends Dog {

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

    }
}


public class Ch06 {

    public static void main(String[] args) {
		// SuperArray 超级数组
        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:在确定了泛型之后,这个超级数组中就统一只放同一类型的数据,如果放入其他类型,编译不通过。

枚举(了解)

应用场景:

​ 在某些情况下,一个类的对象的个数是有限的,

​ 如季节,春夏秋冬,比如24节气,星期。。。

​ 作用是规定这个类的对象的个数。

大更新
JDK1.5更新了枚举类 枚举在switch中可使用

枚举类:

​ 枚举类的命名规则:所有的枚举类要以Enum结尾。

​ 把需要用到的对象声明出来

​ 写对应的构造器

​ 可以有set,get方法

举例说明
public enum SeasonEnum {

    SPRING(1,"春天"),
    SUMMER(2,"夏天"),
    AUTUMN(3,"秋天"),
    WINNER(4,"冬天");

    // public static final SeasonEnum SPRING = new Season(1,"春天");

    private Integer value;
    private String name;

    SeasonEnum(Integer value, String name) {
        this.value = value;
        this.name = name;
    }

    public Integer getValue() {
        return value;
    }

    public void setValue(Integer value) {
        this.value = value;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
枚举的静态导入

​ 需要导入全名

​ *号代表导入枚举类的所有对象

举例说明
//import.static com.jsoft.afternoon.SeasonEnum.SPRING
import static com.jsoft.afternoon.SeasonEnum.*;

public class Ch04 {

    public static void main(String[] args) {
        System.out.println(SPRING.getName());
    }
}
单例模式

​ 使用枚举类实现单例模式。

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

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类型,语义不够明确。

枚举里面都是常量,静态
推荐枚举的比较使用 ==

标签:笔记,class,枚举,20220801,static,大禹,泛型,new,public
来源: https://www.cnblogs.com/ldydj/p/16542127.html