美文网首页
java 基础回顾 - 泛型

java 基础回顾 - 泛型

作者: __Y_Q | 来源:发表于2020-09-23 16:14 被阅读0次
  • 泛型在使用时确定, 但如果提前知道泛型也可以在定义时确定泛型类型, 但这样做体现不了泛型的优势与强大.
  • 泛型不存在继承, 即在确定了泛型时, 其操作用相对应的泛型必须一致, 不能存在继承或者多态的关系. 即<> 内的类型必须一致, 不能不同. 但是使用泛型的对象依然是可以存在继承或者多态的关系. 即<> 外的东西存在继承或者多态.
  • 泛型只能是引用类型, 不能是基本类型.

1. 泛型的定义 - 定义在类上

作用域在类上, 在任何地方出现都代表是同一类型, 可以参考 ArrayList<T>
定义在类上的泛型是在创建对象时确定的

/*
* 定义具有泛型的类
* 修饰符 class 类名 <范型变量>{
*      范型变量一般用E,K,V,T;
* }
* */
public class MyClass1<E> {
    private E e;

    public MyClass1() {
    }

    public MyClass1(E e) {
        this.e = e;
    }

    public E getE() {
        return e;
    }

    public void setE(E e) {
        this.e = e;
    }

    @Override
    public String toString() {
        return "MyClass1{" +
                "e=" + e +
                '}';
    }

    public void print(){
        System.out.println(e);
    }
}

使用

MyClass1<String> stringMyClass1 = new MyClass1<>();
stringMyClass1.setE("张三");
String str = stringMyClass1.getE();

 

2. 泛型的定义 - 定义在方法上

定义在方法上的泛型是在真正调用方法的时候才确定, 一般由传入的参数确定, 包含这个方法的类创建对象时, 并不会确定方法上的类型. 定义泛型方法, 是先声明后使用.

/*
  泛型方法(方法上含有泛型)
  格式:
  修饰符 <声明泛型变量> 返回值类型 方法名称(参数列表...) {
      //...
  }
 */
private <K> K show(K k){
   return k;
}

使用

String s = show("333");
Integer integer = show(123);

 

3. 泛型的定义 - 泛型的上限和下限以及通配符

  • 通配符 ?
    在使用泛型类或者接口时, 在传递的数据中, 泛型类型不明确, 可以使用通配符 <?> 表示, 但是一旦使用泛型的通配符之后, 里面的只能使用 Object 类中的共性方法, 集合中元素自身方法无法使用, 具体如下所示.
    /*
    * 泛型在使用时必须左右一致,不存在继承;
    * */
    public static void main(String[] args) {
        ArrayList<?> list1 ;
        ArrayList<String> list2 = new ArrayList<String>();
        ArrayList<Integer> list3 = new ArrayList<Integer>();
        //下面这行代码会报错,泛型在使用时必须左右一致,不存在继承
        ArrayList<Object> list4 = new ArrayList<String>();
        //下面两行代码不会报错,使用了通配符,通配符表示任意类型,这是在使用,把?当成任何一种类型,
        //?就是任何类型。
        list1 = list2;
        list1 = list3;
        //这行代码会报错  因为两者在定义时使用泛型,一旦确定了类型就不能够改变类型,
        //只能是给定的一种泛型类型。
        list2 = list3; 
    }

上面说明了 为什么泛型在使用的时候必须左右一致.

    public static void print1(ArrayList<?> list) {
        //使用了通配符里面的元素被限定了只能使用Object的方法,
        //底层使用的是Object所以不能添加元素,因为不知道里面到底是什么类型的元素
        list.add(new Object());  //会报错
        list.get(0);
        list.remove(0);
        list.set(0,new Object());  //会报错
        for(Object obj : list) {
            System.out.println(obj);
        }
    }
  • 泛型的上限和下限
    当使用通配符的时, 我们不想 <?> 代表所有类型, 我们相对类型有一定的限定, 这时候就需要用到上限和下限了. <? extends 类名> 意思是 ? 能代表的类型只能是指定类名的子类, 所以叫做上限.
    <? super 类名> 意思是 ? 能代表的类型只能是指定类名的父类, 所以叫做下限.
    下面用两个例子来说明一下上限和下限
    上限: 我们每次 startActivity 的时候不想都写两行代码去 startActivity 于是我们新建了一个 BaseActivity, 于是变成了这样
public class BaseActivity extends Activity {
    public void startActivity(Class clazz){
        Intent intent = new Intent(this, clazz);
        startActivity(intent);
    }
}

public class MyActivity extends BaseActivity {
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        startActivity(MainActivity.class);
    }
}

但是在使用过程中, 我们发现在之类中调用父类的 startActivity 的时候, 无论传什么进去都可以, 什么String.class, Intent.class, Activity.class 都可以也不会报错, 这样就不爽了, 我们想接收的只是 Activity , 于是我们接着对 BaseActivitystartActivity 方法进行改造. 只接收继承自 Activityclass. 变成了下面这样.

public class BaseActivity extends Activity {
    public void startActivity(Class<? extends Activity> clazz) {
        Intent intent = new Intent(this, clazz);
        startActivity(intent);
    }
}

又或者是只接收有继承了 BaseActivityclass.

public class BaseActivity extends Activity {
    public void startActivity(Class<? extends BaseActivity> clazz) {
        Intent intent = new Intent(this, clazz);
        startActivity(intent);
    }
}

这样传入的非继承自 Activity 或者 BaseActivity 的那些类就会直接报错. 这就是泛型的上限, 无论你传入参数的中间继承了多少次, 只要最顶层是继承自 BaseActivity 就可以.


下限: 可以简单的理解为, 传入的参数最低要求都是指定的类名或者指定类名的父类. 这个我们一般不常用. 这里就不再举例,

相关文章

  • java 基础回顾 - 泛型

    泛型在使用时确定, 但如果提前知道泛型也可以在定义时确定泛型类型, 但这样做体现不了泛型的优势与强大. 泛型不存在...

  • Java泛型:类型擦除

    前情回顾 Java泛型:泛型类、泛型接口和泛型方法 类型擦除 代码片段一 显然在平时使用中,ArrayList (...

  • Java 泛型

    导读 移动开发知识体系总章(Java基础、Android、Flutter) 为什么会有泛型? 泛型类 泛型方法 泛...

  • Java泛型教程

    Java泛型教程导航 Java 泛型概述 Java泛型环境设置 Java泛型通用类 Java泛型类型参数命名约定 ...

  • Java基础之泛型

    Java基础之泛型 泛型基本介绍 简单介绍在jdk1.6之前,还没有使用到泛型,Java类型分为原始类型、复杂类型...

  • spring 泛型处理

    java 泛型基础 泛型类型:泛型类型是在类型上参数化的泛型类或接口 泛型使用场景编译时前类型检查。定义为 Col...

  • Java泛型基础

    Java泛型基础 1. 认识泛型 泛型是在JDK1.5之后增加的新功能. 泛型可以解决数据的安全性问题, 主要的原...

  • 一文带你认识Java泛型基础

    Java泛型基础 1. 认识泛型 泛型是在JDK1.5之后增加的新功能. 泛型可以解决数据的安全性问题, 主要的原...

  • 第二十八课:泛型

    泛型出现之前 泛型出现之后 Java深度历险(五)——Java泛型

  • Java基础(一)

    Java要点1 JAVA基础 1.对抽象、继承、多态的理解 2.泛型的作用及使用场景 1.Java泛型是JDK1....

网友评论

      本文标题:java 基础回顾 - 泛型

      本文链接:https://www.haomeiwen.com/subject/wrkoyktx.html