1.泛型
泛型能帮助我们把【类型明确】的工作推迟到创建对象或调用方法的时候。我们定义类的时候,不需要考虑这个数组到底要存什么类型。
1.1泛型的修饰
-
泛型类
-
把泛型定义在类上,用户在使用类的时候才能把类型给确定
- 使用方法在<>加上一个未知数。通常用T,K,V等大写字母。(实际上用什么都行,只要是个单词)
-
如果一个泛型类,在创建对象的时候没有指定泛型的类型还是默认的Object
-
在使用这个类的时候去确定这个泛型的类型。
-
SuperArray<String> array = new SuperArray<>(); array.add("是"); // 现在这个超级数组只能存String类型 array.add(1);
-
// 泛型的三种写法 SuperArray<String> array = new SuperArray<>(); // 推荐下边的这个写法 SuperArray<Ch01> array1 = new SuperArray<>(); // JDK7以前的完整写法,JDK7以后可以省略等号右边的声明,<>必须写 SuperArray<Ch01> array2 = new SuperArray<Ch01>();
-
-
-
泛型方法
-
有泛型的声明才叫泛型方法,在方法里传泛型参数不是泛型方法。
-
泛型方法不一定在泛型类里,泛型类里不一定要有泛型方法。
-
在定义泛型方法时,要首先定义泛型类型——定义在方法中间,泛型的使用处之前.
-
// 使用泛型方法一定要传参数,但是可以没有返回值 public <T> T dd(T t){ return t; } // 通过方法的实参来确定泛型的类型 new Ch01().dd(“1”); // String类型的
-
-
学习重点:要知道什么样的方法叫泛型方法
-
-
泛型接口
- 同泛型类一样
-
如果在一个泛型类中,尽量就不要再使用泛型方法——泛型方法多数都出现再非泛型类
1.2泛型类继承
泛型类在继承时:
-
父类是泛型类,子类可以不是泛型类
-
永远记住,泛型的声明只能在当前类名后或者方法中间
-
在子类继承父类时,子类泛型和父类泛型都写出来的情况下,父跟子
-
class Father<T> { } // 在确定子类泛型的时候,父类的泛型和子类一样 class Son<T> extends Father<T>{ }
-
-
如果在继承的时候,没有写出任何泛型,当前子类就不是泛型类
-
静态泛型方法:
- 静态方法如果是泛型方法,泛型的声明必须写。
- 因为静态结构是属于类的,不属于某个对象。
-
// ?叫通配符 // 可以接受任何类型. // 传入 Animal和它的子类 public static void show(SuperArray<? extends Animal> superArray){ } // 传入 Teddy和它的父类 public static void show1(SuperArray<? super Teddy> superArray){ }
1.3类型擦除
-
泛型——类型参数化
-
为了兼容性,使用原始类型(没有泛型)是可以的。
- 泛型刚刚出现的时候,还是存在大量的不适用泛型的代码。
- 保证代码的兼容性,将参数化类型的实例传递给设计用于原始类型的方法必须是合法的。
- 为了保持兼容性,Java泛型中,其实有一种类似伪泛型,因为Java在编译期间,所有的泛型都会被擦掉。
-
Java的泛型语法是在编译器这个维度上实现的。
- 正常在生成的字节码文件中,不包含泛型的类型信息的。
- 由泛型附加的类型信息对JVM是看不到的。
- 泛型的本质就是让程序员在编写代码时遵守的一个规则。
-
开发经验:能够在业务上解决的问题,尽量不要在技术上解决
1.4泛型的应用场景
- 父类(接口):起到的是一个规范的作用,对里面的数据类型没有明确的要求。
- 容器类(链表,队列,栈)
- 当类型无法确定时使用泛型
- 在开发中,我们更多的是会使用到一些泛型类或泛型接口。
1.5总结
- 泛型不能是基本数据类型,用包装器类型
- 数组原则是可以作为泛型,语法的角度<>里面放的就应该是类名。数组在编译后才会生成一个类($~~)
- 方法的重载:
- 在同一个类
- 方法名相同
- 参数不同
- 泛型不同不能作为方法重载——因为类型擦除。
- 多态上(子类父类)。
2.枚举类型
应用场景:一个类的对象是有限的(规定/限制这个类对象的个数)。
2.1枚举结构
public enum Ch01 {
// 把需要用到的对象声明出来
// 常量
SPRING("13",1), // 后面用逗号连接,最后一个常量用分号
SUMMER("13",1),
AUTMUMN("13",1),
WINNER("13",1);
private String name;
private Integer value;
// 构造器私有化
Ch01() {
}
Ch01(String name, Integer value) {
this.name = name;
this.value = value;
}
// 可以有get,set方法
}
2.2枚举的静态导入
// *号代表导入枚举类的所有对象
import static com.gyc.afternoon.Ch01.*;
2.3枚举类单例模式
书——高效Java
class Singleton{
// 私有化构造器
private Singleton(){
}
// 提供共有的获取实例的静态方法
public static Singleton getInstance(){
return SingletonHolder.INSTANT.instant;
}
//声明一个枚举类(内部类)
private enum SingletonHolder{
INSTANT;
private final Singleton instant;
SingletonHolder() {
instant=new Singleton();
}
}
}
2.4枚举的优势
- int类型不具备安全性。例——假如定义int的时候少写了个final,会存在被他人修改的风险。如果是枚举类,它天然就是一个常量类。
- 使用int类型,定义的语义不够明确。
- 枚举的比较推荐使用==
3.多线程入门
- 在执行程序的时候,实时的指令加载到cpu内存的指令寄存器中执行。——执行的过程中产生的数据要加载到数据寄存器中。ALU负责进行算术逻辑运算的操作。
- 系统总线:连续计算机系统的主要组件,用来降低成本和促进模块化。可以通过软件来控制硬件。
- 进程:
- 一个正在执行中的程序就是一个进程。系统就会为这个进程发配独立的【运行资源】。
- 进程是程序的一次执行过程,它有自己的生命周期
- 启动程序时产生。
- 运行程序时存在。
- 关闭程序时消亡。
- 进程更强调的是【内存资源分配】
- 线程:
- 线程是由进程创建的,是进程的一个实体,(是具体干活的人)。
- 一个进程有多个线程。线程不独立分配内存,而是共享进程的内存资源。
- 线程是可以共享CPU分配的资源。
- 线程更强调的是【计算的资源的分配】
- 一个进程的线程不能修改另一个线程的数据——线程之间相互隔离,安全性更好。
总结
- 泛型类泛型接口的应用,何时确定泛型类型
- 枚举类的声明和使用
- 什么是进程