参数化类型,使用广泛的类型
==使用泛型的原因==:数据类型不明确;装入数据的类型都被当成Object对待,从而丢失实际类型;获取数据时往往需要转型,效率低,且容易产生错误;
==使用泛型的作用==:安全:编译时检查类型安全;
省心:所有的转换都是自动 和隐式的,提高代码重用率;
==泛型不能使用在静态方法和属性上==: 自定义泛型是在使用时确定类型,静态的是在编译时确定类型,冲突
不使用泛型时的代码(繁琐):
1.Student
package com.alexanderli95.gen;
/**
* Object可以储存任何类型,发生多态
*/
public class Student {
private Object javase;
private Object mysql;
public Student(Object javase, Object mysql) {
this.javase = javase;
this.mysql = mysql;
}
public Student() {
}
public Object getJavase() {
return javase;
}
public void setJavase(Object javase) {
this.javase = javase;
}
public Object getMysql() {
return mysql;
}
public void setMysql(Object mysql) {
this.mysql = mysql;
}
}
2,App
package com.alexanderli95.gen;
public class App {
public static void main(String[] args) {
// 存整数, int->Integer->Object , 自动装箱
Student stu=new Student(80,90);
//Object->Integer->int , 自动拆箱
int javaseScore=(int )stu.getJavase();
System.out.println(javaseScore);
String mysqlScore=null;
if(stu.getMysql() instanceof String){ //手动类型检查,避免java.lang.ClassCastException
mysqlScore=(String)stu.getMysql();
System.out.println(mysqlScore);
}
}
}
==常见字母==:
T:Type类型; K V:Key Value,键值;E:Element;?:不确定类型
==不能使用在静态属性,静态方法上==
==使用时不能指定基本数据类型(使用引用类型)==
使用时才确定具体类型
接口中泛型字母只能使用在方法中,不能使用在全局常量中
eg:
package com.alexanderli95.gen02;
public class Student<T1,T2> { //定义
private T1 javaseScore;
private T2 mysqlScore;
public Student(T1 javaseScore, T2 mysqlScore) {
this.javaseScore = javaseScore;
this.mysqlScore = mysqlScore;
}
public Student() {
}
public T1 getJavaseScore() {
return javaseScore;
}
public void setJavaseScore(T1 javaseScore) {
this.javaseScore = javaseScore;
}
public T2 getMysqlScore() {
return mysqlScore;
}
public void setMysqlScore(T2 mysqlScore) {
this.mysqlScore = mysqlScore;
}
public static void main(String[] args) {
Student<Integer,String> stu=new Student<Integer, String>(80,"90"); //使用时确定类型
}
}
package com.alexanderli95.gen02;
public interface Comparator <T> {
Integer a=0; //T a=0; 报错
public T b();
}
==定义==:
修饰符<字母> 返回类型 方法名(字母){...}
泛型可以定义在方法中,是否拥有泛型方法与其所在的类是否是泛型类没有关系
package com.alexanderli95.gen02;
import java.io.Closeable;
import java.io.IOException;
public class TestMethod {
public static void main(String[] args) {
test("a"); //T->String
}
public static <T> void test(T t){ //泛型方法定义
System.out.println(t);
}
// extends在这里表示小于等于后面的类型,T只能是Closeable的实现类
public static <T extends Closeable> void test(T... t){ //泛型方法定义,T加...表示改变参数
for(T temp:t){
try {
if(temp!=null) {
temp.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
接口的使用与类一样
子类与父类/接口一样使用泛型;
public abstract class Father <T>{
private T data;
public abstract void test(T t);
}
// 子类为泛型类,则具体类型在使用时才确定
class Son2<T> extends Father<T>{
T data;
@Override
public void test(T t) {
}
}
子类指定具体的类型;
//子类声明时指定具体类型
//属性类型为具体类型,方法同理
class Son1 extends Father<String> implements Comparator<String>{
String data;
@Override
public void test(String s) {
}
@Override
public String b() {
return "Comparator";
}
}
子类擦除类型;
public abstract class Father <T>{
private T data;
public abstract void test(T t);
}
//子类为泛型类,父类不指定类型,即为泛型的擦除,使用Object替换
class Son3<T,T1> extends Father{
@Override
public void test(Object o) {
}
}
子类与父类/接口同时擦除类型;
public abstract class Father <T>{
private T data;
public abstract void test(T t);
}
//子类与父类同时擦除
class Son4 extends Father{
@Override
public void test(Object o) {
}
}
==擦除统一使用Object对待==
要么同时擦除,要么子类大于等于父类的类型,不能子类擦除,父类泛型;
1.属性类型:父类中,随父类而定,子类中,随子类而定
2.方法重写:随父类而定
? extends super
1.可以用在声明类型和声明方法参数上,不能用在声明类上
2.?可以接受泛型的任何类型,只能接收和输出,不能修改
==泛型没有多态==
package com.alexanderli95.gen02;
/**
* 泛型,?的使用方式
* 只能用在声明类型和方法上,不能使用时或者声明类
* ? extends: <= 上限
* ? super: >=下限
*/
public class A <T>{
T score;
public static void main(String[] args) {
A<?> a=new A<String>();
test(new A<Integer>());
//<=
test2(new A<XiaoMing>());
//>=
test3(new A<Object>());
}
public static void test(A<?> stu) {
}
//<= 使用时只能传Student的子类类型进去
public static void test2(A<? extends Student> stu){
}
//>= 使用时只能传Student的父类类型进去
public static void test3(A<? super Student> stu){
}
}
==声明==:嵌套适用类型
A<B<C>> a=new A<B<C>>();
==使用==:从外到内,一层层的拆分
package com.alexanderli95.gen02;
public class TestQianTao <T>{
T stu;
public static void main(String[] args) {
TestQianTao<Student<String,Integer>> room=new TestQianTao<Student<String,Integer>>();
room.stu=new Student<String,Integer>();
Student<String,Integer> stu2=room.stu;
String score=stu2.getJavaseScore();
}
}
没有泛型数组,不能创建(开辟空间)泛型数组
可以只有声明,可以使用?
A[] a1=null;
A[] a2=new A[10];
所以泛型数组没有意义
A a=new A<>(); 声明一次类型即可
使用和创建时不用指定类型;