JavaSE高级部分

  1. 泛型
  2. 枚举
  3. 多线程
  4. 集合(数据结构)
  5. IO流(操作文件)
  6. 反射和注解
  7. 网络通信Socket

泛型(Generics)

  1. 泛型:广泛的、普通的类型
  2. 泛型能够帮助我们把[类型明确]的工作推迟到创建对象或者调方法的时候
public class MyClass<T>{
    T value1;
    T value2;
}
  1. 类声明后的<>中这个T被称为类型参数,用于指代任意类型
  2. 具体的使用方法:<>加上一个未知数,出于规范,类型参数用单个的大写字母来代替,常见如下:
  • T:代表任意类
  • E:表示Element的意思,或是异常
  • K:与V搭配使用
  • V:与K搭配使用
  1. 泛型不能是基本数据类型,<>里面放的就应该是类名,数组是在编译后才会生成一个类
  2. 方法重载:a.同一个类里 b.方法名相同 c.参数不同
  3. 多态上

泛型方法

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

  1. 泛型方法不一定要在泛型类里
  2. 泛型类里不一定要有泛型方法
  3. 如果在一个泛型类中,尽量不要使用泛型方法
  4. 泛型方法多数都是出现在非泛型类

静态方法

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

在定义泛型方法时,首先要定义泛型类型,泛型类型定义在方法中间,泛型的使用处之前
使用泛型方法,最好要结合返回值,和Object一样

public class Ch03 {
    public <T> T show(T t)
    return t;
}

泛型类的继承关系

泛型类在继承时:

  1. 父类是一个泛型类,子类不一定是泛型类
  2. 泛型的声明只能在当前类名后或方法中间,而且泛型的声明是自身的
  3. 在子类继承父类时,子类泛型和父类泛型都写出来的情况下是父跟子
  4. 如果在继承时,没有写出任何泛型,当前子类就不是泛型类
class Father<T>{

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

    }
class Son2 extends Father{

    }
}

通配符

? 用于在泛型的使用,即为通配符

  • 上界通配符:
语法:<? extends 上界>
举例:<? extends Number>//可以传入的实参类型是Number或者Number的子类
  • 下界通配符:
语法: <? super 下界>
举例:<? super Integer>//代表 可以传入的实参的类型是Integer或者Integer的父类类型

类型擦除

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

泛型的应用场景

  1. 父类(接口),起到的是一个规范的作用,对里面的数据类型没有明确要求
  2. 容器类 (超级数组、链表、队列、栈)

枚举

应用场景:

  1. 在某些情况下,一个类的对象的个数是有限的
  2. 如季节,春夏秋冬.....

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

规定这个类的对象的个数

使用枚举类实现单例模式

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

class Singleton{

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

    //提供公用的获取实例的静态方法
    public static Singleton getInstance(){
        return SingletonHolder.INSTANT.instant;
    }
    //声明一个枚举类(内部类)
    private enum SingletonHolder{
        INSTANT;

        private final Singleton instant;

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

}

进程

  1. 一个正在执行中的程序就是一个进程,系统就会为这个进程发配独立的【运行资源】
  2. 进程是程序的一次执行过程,它有自己的生命周期
  3. 它会在启动程序时产生
  4. 运行程序时存在
  5. 关闭程序时消亡

线程是由进程创建,是进程的一个实体,是具体干活的人
一个进程有多个线程。线程不独立分配内存,而是共享进程的内存资源,线程可以共享cpu资源。
进程更强调的是【内存资源分配】,线程更强调的是【计算的资源的分配】
因为有了线程的概念,一个进程的线程不能修改另一个线程的数据,线程之间是相互隔离的,安全性更好。