通配符(?/? extends 类/ ? super 类)

先看一个例子:

class Message<T>
{
    private T message;

    public T getMessage()
    {
        return message;
    }
    public void setMessage(T message)
    {
        this.message=message;
    }
}
public class Tong
{
    public static void main(String[] args)
    {
        Message<String> m1=new Message<>();
        m1.setMessage("pick");
        func(m1);

        Message<Integer> m2=new Message<>();
        m2.setMessage(10);
        //func(m2);  //这里会出错,如果func形参指定类型,就要重载一个形参为Integer的func

    }
    public static void func(Message<String> m)
    {
        System.out.println(m.getMessage());
    }
}

为什么会有通配符?
上述例子需要写很多重载方法,但是写重载方法的本质上是为了func可以接受不同的泛型,而通配符就可以接受任意类型。

通配符-----?

  • ?通配符:表示参数可以接收任意类型 ,只能用于方法
  • ? 通配符只能取得类中属性值,不能修改属性值,因为类型不确定,无法设置确定类型。
    用通配符对上述例子进行修改:
 public static void func(Message<?> m)
    {
        //此时使用通配符"?"描述的是它可以接收任意类型,但是由于不确定类型,所以无法修改
        //m.setMessage("world"); //错误,不能修改数据
        System.out.println(m.getMessage());
    }

通配符----? extends 类

  • ? extends 类 是设置泛型上限,表示泛型类是类或者类的子类;
  • ? extends 类 可以用于类和方法
  • ? extends 类用于方法时,不能修改属性值,只能取得属性值,因为发生了父类(如Number)到子类的向下转型,需要强转,由于子类不确定,无法强转。

如:? extends Number 表示只能设置Number及其子类如Integer 、Double等。

T extends 类 : 用在类上
表示T只能是类或类的子类。

?extends 类: 用在方法上
表示只能接受类及其子类的泛型类。

////通配符----? extends 类

class Mess<T extends Number>  //T只能是Number及其子类
{
    private  T mess;
    public void setMess(T mess)
    {
        this.mess=mess;
    }
    public T getMess()
    {
        return this.mess;
    }
}

public class Tong
{
    public static void main(String[] args)
    {
        //Mess<String> m1=new Mess<String>();  //错误,因为String不是Number的子类
        Mess<Integer> m2=new Mess<>();
        m2.setMess(10);  //自动装箱
        func(m2);

        Mess<Double> m3=new Mess<>();
        m3.setMess(19.3);
        func(m3);
    }
    public static void func(Mess<? extends Number> m)
    {
        //此时?继承了Number类,但依旧不知道具体类型,即无法修改数据
        //m.setMess(10);//错误
        System.out.println(m.getMess());
    }
}

通配符----- ? super 类

  • ? super 类: 表示取得泛型下限,表示泛型类只能是类和类的父类;
  • ?super 类 :只能用于方法
  • ? super 类用在方法中可以设置属性值,也可以取得属性值,因为子类到父类是自动的向上转型。

如:? super String :表示此方法只能取得String及其父类Object类。

class Met<T>
{
    private T met;
    public void setMet(T met)
    {
        this.met=met;
    }
    public T getMet()
    {
        return this.met;
    }
}

public class Tong
{
    public static void main(String[] args)
    {
       Met<String> m1=new Met<>();
       m1.setMet("pick");
       func(m1);  //接收String类

    }
    public static void func(Met<? super String> m)
    {
        m.setMet("world");  //可以设置属性:子类到父类是自动转型
        System.out.println(m.getMet());
    }
}

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/sophia__yu/article/details/83755466