目录
从今天开始我们学的就是JavaSE高级部分:
- 泛型
- 枚举
- 多线程*(最难的,也是最重要的)
- 集合
- IO流
- 反射和注解
- 网络通信Socket
泛型(Generics)
什么是泛型?
泛型:广泛的、普通的类型。
泛型能够帮助我们把【类型明确】的工作推迟到创建对象或者调方法的时候。
意思就是:我定义类的时候,我不需要考虑这个数组到底要存是那么类型。
泛型的修饰:
1.泛型类
2.泛型方法
3.泛型接口
泛型类把泛型定义在类上,这样用户在使用类的时候才能把类型确定。
具体使用方法:<>加上一个未知数。通常用大写字母(T K V)表示,实际上用啥都行,只要是个单词就可以。
public class A<T> {}
当我们在一个类后面加上了泛型<T>,这个T就是一个数据类型。
既然T就是一个数据类型,那我们就可以拿过来用
声明一个T类型的变量t:
private T t;
如果一个泛型类,在创建对象的时候没有指定泛型类型,默认还是Object,在使用这个类的时候,去确定泛型类型.
SuperArray<String> S=new SuperArray();//不规范,不要这么写
SuperArray<Employee> superArray=new SuperArray<>();
//在JDK7以后,可以省略等号右边的泛型的声明,<>必须得写,不写<>不规范。
SuperArray<Employee> superArray1=new SuperArray<Employee>();
泛型方法:
我们如果只关心某个方法,可以不定义泛型类。只定义一个泛型方法。
泛型方法是不是一定要在泛型类里?不是
泛型类里是不是一定要有泛型方法?也不是
在定义泛型方法时,要首先定义泛型类型。定义在方法中间,泛型的使用处之前
使用泛型方法,最好要结合返回值,和Object一样。
public <T> T show(T t){
// 拿着这个t在方法中做好多事情,再把t返回去
//调用另一个方法
System.out.println(t);
return t;
//也可以抛异常哟---不重要
}
泛型的继承关系:
1.父类是一个泛型类,子类要不要也是泛型类?
2.永远记住,泛型的声明只能在当前类名后或者方法中间,而且声明的泛型是自己的,和别人没有什么关系。
3.在子类继承父类时,子类泛型和父类泛型都写出来的情况下,父跟子
4.如果在继承时,没有写出任何泛型,当前子类就不是泛型类。是Object类
class Father<T>{
T t;
}
class Son<T> extends Father<T>{
//在确定子类泛型的某一时刻,你父类的泛型和子类一样。通过子类
}
class Son2 extends Father{ }
public class Test04 {
public static void main(String[] args) {
Son<Employee> stringSon=new Son<>();
stringSon.t=new Employee();
Son2 s=new Son2();
s.t.toString();
}
}
如果在一个泛型类中,尽量就不要在使用泛型方法。
泛型方法多数都是出现在非泛型类
静态泛型方法
1.静态方法如果是泛型方法,泛型的声明必须写。
2.因为静态结构是属于类的,不属于某个对象
interface Inter<T>{
<T> T show(T t);
static <T> T info(T t){
return t;
}
}
class Demo<T> implements Inter<T>{
@Override
public <T> T show(T t){
return t;
}
}
通配符:?代表上一个类/对象/属性/包的所有
类型擦除:
为了一些兼容性:使用到原始的类型(没有泛型),是可以的。
在泛型刚刚出现的时候,还是存在大量的不适用泛型的代码。
保证代码的兼容性,将参数化类型的实例传递给设计用于原始类型的方法必须合法的
为了保持兼容性:
在Java的泛型中,其实有一种类似的伪泛型,因为JAVA编译期间所有的泛型都会被擦掉
Java的泛型语法是在编译期这个维度上实现的。
正常来说在生成的字节码文件中卖不包含泛型的类型信息的。
在JVM中看到的只是SuperArray,由泛型附加的类型信息对JVM是看不到的
可以理解为,泛型的本质就是让程序员在编写代码时遵守的一个规则
比如SuperArray:在确定了泛型之后,在这个超级数组中就统一只放同一类型的
如果放入其他类型,编译不通过
1.泛型不能是基本数据类型。(原则上来说,数组可以作为泛型,语法角度,不可以)
<>里面放的就应该是类名。数组是在编译后才会生成一个类($xxxx)
2.方法重载:a.同一个类里 b.方法名相同 c.参数不同
原理:类型擦除。
3.多态上。
泛型的应用场景:
1.父类(接口),起到的是一个规范的作用,对里面的数据类型没有明确要求。
2.容器类。(超级数组,链表,队列,栈)
当类型无法确定时,使用泛型。
开发中,我们更多的是会使用到一些泛型类或泛型接口。