关于泛型(Generics)

本文详细介绍了Java泛型的概念、作用,展示了如何在类、接口和方法中使用泛型,并通过实例演示了参数可变泛型和通配符上下限。重点讲解了泛型在编译期的优势及常见误区,适合开发者提升代码质量和安全性。
摘要由CSDN通过智能技术生成

1.什么是泛型

泛型是指参数化类型。就是把类型像参数一样传递

2.泛型的作用

1.代码可读性更好[不用强制转换]
2.程序更加安全[只要编译时期没有警告,运行时期就不会出现 ClassCastException 异常]

3.泛型的定义

泛型字符

泛型字符可以是任何标识符,一般采用几个标记:E T K V N。

泛型标记对应单词说明
Eelement
在容器中使用,表示容器中的元素
Ttype
表示普通的 JAVA 类
Kkey
表示键,例如:Map 中的键 Key
Vvalue表示值
NNumber表示数值类型
表示不确定的 JAVA 类型

泛型类

public class 类名<泛型标识符>{

}

public class Generic<T> {
    private T flag;
    public void setFlag(T flag){
        this.flag = flag;
    }
    public T getFlag(){
        return this.flag;
    }
}

泛型接口

public interface 接口名<泛型标识符>{

}

public interface Interface1<T> {
    T fun(T name);
}

实现接口泛型类

非静态方法 且 无返回值(void)

public <泛型标识符> void fun(<泛型标识符> a){

}

    public void setFlag(T flag){
        this.flag = flag;
    }

非静态方法 且 有返回值

public <泛型标识符> <泛型标识符> fun(<泛型标识符> a){

}

    public T getFlag(){
        return this.flag;
    }

对上面两个方法的test

// 泛型测试
public class Test {
    public static void main(String[] args) {

        Generic<String> generic = new Generic<>();
        generic.setFlag("xdw");
        String flag = generic.getFlag();
        System.out.println(flag);
        //
        Generic<Integer> generic1 = new Generic<>();
        generic1.setFlag(100);
        Integer flag1 = generic1.getFlag();
        System.out.println(flag1);
    }
}
// 输出为
//xdw
//100

参数可变泛型方法

public <泛型标识符> <泛型标识符> fun(<泛型标识符>...a){

}

public class args_generic_test {
    public static void main(String[] args) {
        EDG edg = new EDG();
        String[] strings = new String[]{"edg","rng","tes"};
        Integer[] integers = new  Integer[]{1,2,3};
        edg.method(strings);
        edg.method(integers);
    }
}
class EDG{
    public <T> void method(T...args){
        for(T t:args){
            System.out.println(t);
        }
    }
}
/*
输出为
edg
rng
tes
1
2
3*/
静态方法中使用泛型时有一种情况需要注意一下,那就是静态方法无法访问类上定义的
泛型;如果静态方法操作的引用数据类型不确定的时候,必须要将泛型定义在方法上。

静态方法 且 无返回值(void)

public static <泛型标识符> void fun(<泛型标识符> a){

}

    public static <T> void getStr(T Str){
        System.out.println("Str:"+Str);
    }

静态方法 且 有返回值

public static <泛型标识符> <泛型标识符> fun(<泛型标识符> a){

}

    public  static  <T> T getStr1(T Str){
        return Str;

test

public class static_method_gengeric_test {
    public static void main(String[] args) {
        A a = new A();
        a.getStr("无返回值静态泛型Test");
        String aa = a.getStr1("有返回值静态泛型Test");
        System.out.println("Str:"+aa);
    }
}

4.通配符上下限定

extends : 上限限定

比如 <? extends Number> 那么传入的类型只能是Number和number的子类

super : 下限限定

比如 <? super Number> 那么传入的类型只能是Number和number的父类(爷爷也可以)

// super 下线限定的test
/*
* 限定能用的是Number和他的父类(包括爷爷)*/
public class limit_generic {
    public static void main(String[] args) {
        A2 a2 = new A2();
        Generic<Integer> generic = new Generic<>(); // 自己
        Generic<Number> generic1 = new Generic<>(); // 父类
//        Generic<String> generic2 = new Generic<>();
        Generic<Object> generic3 = new Generic<>(); // 爷爷
        generic.setFlag(11);
        a2.method2(generic);
        generic1.setFlag(50);
        a2.method2(generic1);
//        a2.method2(generic2);
        generic3.setFlag(555);
        a2.method2(generic3);
    }
}
class A2{
    public void method2(Generic<? super Integer> name){
        System.out.println("通配符下线限定");
        System.out.println("限定类型为Integer和它的父类");
        System.out.println("当前的值:"+name.getFlag());
    }
}

5.总结

    泛型主要用于编译阶段,编译后生成的字节码 class 文件不包含泛型中的类型信息。

类型参数在编译后会被替换成 Object,运行时虚拟机并不知道泛型。

因此,使用泛型时,如下 几种情况是错误的:

1. 基本类型不能用于泛型。 Test<int> t; 这样写法是错误,我们可以使用对应的包装类;Test<Integer> t ;

2. 不能通过类型参数创建对象。 T elm = new T(); 运行时类型参数 T 会被替换成 Object,无法创建 T 类型的对象,容 易引起误解,所以在 Java 中不支持这种写法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值