当前位置: 移动技术网 > IT编程>开发语言>Java > java中的泛型(基础篇)

java中的泛型(基础篇)

2020年07月17日  | 移动技术网IT编程  | 我要评论
这里写目录标题什么是泛型泛型的分类通配符? 无界通配符上界通配符 < ? extends E>(4) 下界通配符 < ? super E>?和 T 的区别Class 和 Class<?>的区别什么是泛型泛型的分类?表示不确定的 java 类型T (type) 表示具体的一个java类型K V (key value) 分别代表java键值中的Key ValueE (element) 代表Element通配符? 无界通配符上界通配符 < ? exte

什么是泛型

泛型即参数化类型,是JDK1.5中引入的一个新特性。 泛型提供了编译时类型安全检测机制,该机制允许程序员在编译时检测到非法的类型。在不创建新的类型的情况下,通过泛型指定的不同类型来控制形参具体限制的类型。换句话说,"泛型"这个术语的意思是:“适用于许多的类型”。
(出自 java编程思想)

1:泛型的使用

在我们平时开发或者查看源码的时候,我们会发现很多的代码都会用到泛型,比如我们常用到的ArratList,为什么它能够同时创建 String,Double等等很多的类型的集合那?如果我们点进源码就会发现,在源码中使用了泛型。接下来我们就来看看泛型到底有哪些吧!

1.1: 字母规范

在定义泛型类时,我们已经提到用于指定泛型的变量是一个大写字母,当然不是的!!!!任意一个大写字母都可以。他们的意义是完全相同的,但为了提高可读性,大家还是用有意义的字母比较好,一般来讲,在不同的情境下使用的字母意义如下:

  • E — Element,常用在java Collection里,如:
  • List,Iterator,Set
  • K,V — Key,Value,代表Map的键值对
  • N — Number,数字
  • T — Type,类型,如String,Integer等等

1.2:泛型接口

// 接口上定义泛型,此处可以随便写标识符号
public interface Things<T> {
    T getThing();
    // 作为返回值

    void setThing(T t);
    //作为参数
}

泛型接口的使用
非泛型类

public class Coding implements Things<String> {

    private String str;

    public Coding(String str) {
        this.str = str;
    }

    @Override
    public String getThing() {
        return this.str;
    }

    @Override
    public void setThing(String s) {

    }

    public static void main(String[] args) {
        Coding coding = new Coding("写代码!");
        System.out.println(coding.getThing());
    }

泛型类

public class Work<T> implements Things<T> {

    private T var;

    public Work(T var) {
        this.setThing(var);
    }

    @Override
    public T getThing() {
        return this.var;
    }

    @Override
    public void setThing(T var) {
        this.var = var ;
    }

    public static void main(String[] args) {
        Work<String> work=new Work<>("工作中!");
        System.out.println(work.getThing());
    }
}

1.3:泛型类

public class DoSome<T> {
    private T x;
    private T y;

    public T getX() {
        return x;
    }

    public void setX(T x) {
        this.x = x;
    }

    public T getY() {
        return y;
    }

    public void setY(T y) {
        this.y = y;
    }

    public static void main(String[] args) {
        DoSome<String> doSome =new DoSome();
        doSome.setX("123");
        System.out.println(doSome.getX());
        DoSome<Integer> doSome1 =new DoSome();
        doSome1.setX(new Integer(100));
        System.out.println(doSome1.getX());
    }

}

尖括号中,你传进去的是什么,T就代表什么类型。这就是泛型的最大作用,我们只需要考虑逻辑实现,就能拿给各种类来用。

1.4:泛型方法

public class FanxingMethodTest {

    public <T> void normalMethod(T t){
        System.out.println("normalMethod: "+t.toString());
    }
    public void method(String str){
        System.out.println("method:"+str.toString());
    }

    public static void main(String[] args) {
        FanxingMethodTest fanxingMethodTest=new FanxingMethodTest();
        fanxingMethodTest.normalMethod(123);
        fanxingMethodTest.normalMethod("字符串");
        fanxingMethodTest.method("123");
    }

}

2: 通配符

2.1: 通配符

非限定通配符

  形如<?>,表示通配符泛型值接受所有类型。

限定通配符上限

  <? extends T>表示该通配符所代表的类型是T类型及T类型的子类。

限定通配符下限

 形如<? super T>,表示通配符所代表的类型是T类型的父类,只能接收T及其三层父类类型。

2.2: ?和 T 的区别

T 代表一种类型 (具体的java类型)
?是通配符,泛指所有类型,一般用于定义一个引用变量,这么做的好处是,如定义一个引用变量,就可以指向多个对象。表示不确定的java类型
T和?运用的地方有点不同,?是定义在引用变量上,T是类上或方法上

  • ArrayList al=new ArrayList();指定集合元素只能是T类型
  • ArrayList<?> al=new ArrayList<?>();集合元素可以是任意类型,这种没有意义,一般是方法中,只是为了说明用法
  • ArrayList<? extends E> al=new ArrayList<? extends E>();
    泛型的限定:
    ? extends E:接收E类型或者E的子类型。
    ?super E:接收E类型或者E的父类型。

2.3: Object跟泛型类区别

Object是所有类的根类,是具体的一个类,使用的时候可能是需要类型强制转换的,但是用T ?等这些的话,在实际用之前类型就已经确定了,不需要强制转换。
追问:
也就是说,这个方法能知道返回的是哪种类型(父类),就用T行了?如果完全不知道的就用?用T的得到的对象就不需要类型转换了,而用?的就必需用强转了!
追答:
第一种是固定的一种泛型,第二种是只要是Object类的子类都可以,换言之,任何类都可以,因为Object是所有类的根基类
固定的泛型指类型是固定的,比如:Interge,String. 就是
<? extends Collection> 这里?代表一个未知的类型,
但是,这个未知的类型实际上是Collection的一个子类,Collection是这个通配符的上限.
举个例子: class Test { }
其中,限定了构造此类实例的时候T是一个确定类型(具体类型),这个类型实现了Collection接口,但是实现 Collection接口的类很多很多,如果针对每一种都要写出具体的子类类型,那也太麻烦了,干脆还不如用Object通用一下。<? extends Collection>其中,?是一个未知类型,是一个通配符泛型,这个类型是实现Collection接口即可。

3: 泛型使用的注意事项

泛型类型参数不能使用基本数据类型指定,基本数据类型要写成其包装类型。
例如使用new ArrayList()是不合法的。因为类型擦除后会替换成Object(如果通过extends设置了上限,则替换成上限类型),int显然无法替换成Object,所以泛型参数必须是引用类型。泛型类型参数是使用new对象时确定。若不指定泛型类型,则默认使用Object类型。在JDK1.7以后,指定泛型可以省略最后"<>"中的类型。

4: 使用泛型的优势

  • 减少了强制类型转换的操作
  • 在编译时期进行类型检查,避免了很多运行时期才能发现的错误

本文地址:https://blog.csdn.net/qq_42843770/article/details/107343288

如您对本文有疑问或者有任何想说的,请 点击进行留言回复,万千网友为您解惑!

相关文章:

验证码:
移动技术网