泛型作用:
安全:在编译的时候检查类型安全;
省心:所有的强制转换都是自动和隐式的,提高代码的重用率;
1.格式:
class 类型<字母列表>{
修饰符 构造器(字母);
修饰符 返回类型 方法(字母)
}
泛型常见字母:
T Type 表示类型
K V 分别代表键值中的Key和Value
E 代表Element
? 表示不确定的类型
注:泛型声明时,字母不能使用在静态属性、静态方法上;
因为泛型是在使用的时候确定的,静态属性、静态方法编译的时候就确定;
2.使用
使用时指定具体的类型,(不能指定基本类型,而是用引用类型)
1)编译时会进行类型检查;
2)获取数据时不需要进行类型转换
例子1:


package com.cy.gen;
/**
* 泛型类:声明时使用泛型
*
*/
public class Student<T1, T2> {
private T1 javaScore;
private T2 oracleScore;
//private static T1 phpScore;
public T1 getJavaScore() {
return javaScore;
}
public void setJavaScore(T1 javaScore) {
this.javaScore = javaScore;
}
public T2 getOracleScore() {
return oracleScore;
}
public void setOracleScore(T2 oracleScore) {
this.oracleScore = oracleScore;
}
public static void main(String[] args) {
Student<String, Integer> stu = new Student<String, Integer>(); //使用时指定类型,引用类型
stu.setJavaScore("优秀"); //类型检查
int oracleScore = stu.getOracleScore(); //自动类型转换
}
}
例子2,泛型接口:


package com.cy.gen;
public interface Comparator<T> {
void compare(T t);
}
例子3:泛型方法:
修饰符 <字母> 返回类型 方法名(字母){
}
要定义泛型方法,只需将泛型参数列表置返回值前;
注:泛型还可以定义在方法中,是否拥有泛型方法,与其所在的类是否泛型没有关系。
package com.cy.gen;
import java.io.Closeable;
import java.io.IOException;
/**
* 泛型方法 <> 返回类型前面
* 只能访问对象的信息,不能修改信息
*/
public class TestMethod {
public static void main(String[] args) {
test("b"); //T --> String
test(1);
}
//泛型方法
public static<T> void test(T t){
//t.setXXX();
System.out.println(t);
}
//extends <=
//T是Closeable接口的实现类 ...代表可变参数
public static<T extends Closeable> void test(T... a){
for(T temp: a){
try {
if(temp!=null) temp.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
3.派生子类
属性类型
方法重写
泛型擦除
例子1:父类为泛型:


package com.cy.gen02;
/**
* 父类为泛型类
* 1.属性
* 2.方法
*
* 要么同时擦除,要么子类大于等于父类的类型
*/
public abstract class Father<T, T1> {
T name;
public abstract void test(T t);
}
/**
* 子类声明时指定具体类型
*/
class Child1 extends Father<String, Integer>{
@Override
public void test(String t) {
}
}
/**
* 子类为泛型类,类型在使用时确定
*/
class Child2<T, T1> extends Father<T, T1>{
@Override
public void test(T t) {
}
}
/**
* 子类为泛型类,父类不指定类型,泛型的擦除,使用Object替换
*/
class Child3<T1, T2> extends Father{
@Override
public void test(Object t) {
}
}
例子2:泛型接口:


package com.cy.gen02;
/**
* 泛型接口: 与继承同理
* 重写方法随父类而定
* @author CY
*
* @param <T>
*/
public interface Comparable<T> {
void compare(T t);
}
//声明子类指定具体类型
class Comp implements Comparable<String>{
@Override
public void compare(String t) {
}
}
//擦除
class Comp1 implements Comparable{
@Override
public void compare(Object t) {
}
}
//父类擦除,子类泛型
class Comp2<T> implements Comparable{
@Override
public void compare(Object t) {
}
}
//子类泛型>=父类泛型
class Comp3<T, T1> implements Comparable<T>{
@Override
public void compare(T t) {
}
}
4.通配符
? extends super
1.可以用在声明类型、声明方法参数上,不能用在声明类上
2.?可以接受泛型的任意类型,只能接收和输出,不能修改。(方法声明时参数无法正确知道具体的类型,因此不能修改)
3.?extends 泛型上限 <= (指定类型为子类或自身)
4. ? super 泛型下限 >= (指定类型为自身或父类)


package com.cy.gen03;
/**通配符
* ? 类型不定,使用时确定类型
* ?使用: 声明类型|声明方法上,不能声明类或使用时用?
*
*
*/
public class Student<T> {
T score;
public static void main(String[] args) {
Student<?> stu = new Student<String>();
test(new Student<Integer>());
test2(new Student<Apple>());
test3(new Student<Fruit>());
}
public static void test(Student<?> stu){
}
// <=
public static void test2(Student<? extends Fruit> stu){
}
// >=
public static void test3(Student<? super Apple> stu){
}
}
class Fruit{
}
class Apple extends Fruit{
}
来源:oschina
链接:https://my.oschina.net/u/4397276/blog/4142856