JAVA---泛型

目录

为什么要用泛型?

泛型格式:

在使用java提供的对象时,什么时候写泛型?

使用泛型的好处:

好处一:

 好处二:

泛型类

泛型方法

 静态方法:

泛型接口

泛型的限定


为什么要用泛型?

因为在定义集合的时候,没有明确存储的数据类型,当存了不同数据类型的元素时会出现错误,这样就有了安全隐患,为了解决这个安全隐患就提出了泛型

泛型格式:

通过<>来定义要操作的引用数据类型

示例:

//定义了一个ArrayList容器,容器中存的数据类型是String类型
ArrayList<String> a1 = new ArrayList<String>();

在使用java提供的对象时,什么时候写泛型?

 通常在集合框架中很常见,只要见到<>就要定义泛型,其中<>是用来接收类型的,当使用集合时,将集合中要存储的数据类型作为参数传递到<>中即可

使用泛型的好处:

  • 将运行时期出现问题ClassCastEcception,转移到了编译时期,方便于程序员解决问题,让运行事情问题减少,安全
  • 避免了强制转换麻烦,而且安全了很多

好处一:

class GennericDemo
{
    public static void main(String[] args)
    {
        ArrayList<String> a1=new ArrayList<String>();
        a1.add("abc01");
        a1.add("abc0991");
        a1.add("abc0991");
    
        a1.add(4);  //会在编译时报错

        Iterator<Stirng> it=a1.iterator();

        while(it.hasNext())
        {
            String s =it.next();
            
            System.out.println(s+":"s.length())
        }
    }
}

 好处二:

//没有泛型时
class LenComparator implements Comparator
{
    public int compare(Object o1,Object o2)
    {
        String s1=(Stirng)o1;
        String s2=(Stirng)o2;
    }
}

//有了泛型之后
class LenComparator implements Comparator<String>
{
    public int compare(String o1,String o2)
    {
        
    }
}

 

泛型类

什么时候定义泛型类?

当类中要操作的引用数据类型不确定的时候,在其定义Object来完成扩展,现在定义泛型来完成扩展

//没有泛型时候定义工具类
class Worker
{

}

class Student
{

}
class Tool
{
    private Object obj;
    public void setObject(Object obj)
    {
        this.obj=obj;
    }
    public Object  getObject()
    {
        return obj;
    }
}

class GenericDemo
{
    Tool t=new Tool();        
    //如果将new Student()换成new Worker(),不会在编译时期出错,会在运行时期出错,不具有安全性
    t.setObject(new Student());
    Worker w=(Worker)t.getObject();
}
//有泛型时候定义工具类
class Worker
{

}

class Student
{

}
class Utils<T>
{
    private T t;
    public void setObject(T t)
    {
        this.t=t;
    }
    public T getObject()
    {
        return t;
    }
}

class GenericDemo
{
    Utils<Worker> u=new Utils<Worker>();
    //如果将new Worker换成new Student(),那将会在编译时期报错
    u.setObject(new Worker());
    //不需要强制转换
    Worker w=u.getObject();
}

泛型类定义的泛型,在整个类中有效,如果被方法使用,那么泛型类的对象明确要操作的具体类型后,所要操作的类型就已经固定了

为了让不同方法可以操作不同类型,而且类型还不确定,那么可以将泛型定义在方法上 

泛型方法

//普通类中的泛型方法
class Demo
{
    public <T> void show(T t)
    {
        System.out.println("show:"+t);
    }
    public <Q> void print(Q q)
    {
        System.out.println("print:"+q);
    }
}

class GenericDemo
{
    public static void main(String[] args)
    {
        Demo d=new Demo();
        d.show("haha");
        d.show(new Integer(4));
    }
}
//输出:
haha
4
//泛型类中的泛型方法
class Demo<T>
{
    public void show(T t)
    {
        System.out.println("show:"+t);
    }
    public <Q> void print(Q q)
    {
        System.out.println("print:"+q);
    }
}

class GenericDemo
{
    public static void main(String[] args)
    {
        Demo<String> d=new Demo<String>();
        //show方法中只能添加string类型,不能添加其他类型
        d.show("haha");
        d.print(5);
        d.print("haha");
    }
}
//输出:
haha
5
haha

 静态方法:

静态方法不可以访问类上定义的泛型(因为静态方法创建的时候对象可能还没创建),如果静态方法操作的应用数据类型不确定,可以将泛型定义在方法上

错误实例

class Demo<T>
{
    public void show(T t)
    {
        System.out.println("show:"+t);
    }
    public <Q> void print(Q q)
    {
        System.out.println("print:"+q);
    }
    //这样会报错
    public static void method(T t)
    {
        System.out.println("method:"+t);
    }
}

正确示例

class Demo<T>
{
    public void show(T t)
    {
        System.out.println("show:"+t);
    }
    public <Q> void print(Q q)
    {
        System.out.println("print:"+q);
    }
    //这样会报错
    public static <W> void method(W w)
    {
        System.out.println("method:"+w);
    }
}
 

泛型接口

//在实现接口的时候规定数据类型
interface inter<T>
{
    void show(T t);
}

class InterImp implements Inter<String>
{
    public void show(String t)
    {
        System.out.println("show:"+t);
    }
}

class GenericDemo
{
    public static void main(String[] args)
    {
        InterImpl i =new InterImpl();
        i.show("haha");
    }
}
//在用类的时候指定类型
interface inter<T>
{
    void show(T t);
}

class InterImp<T> implements Inter<T>
{
    public void show(T t)
    {
        System.out.println("show:"+t);
    }
}

class GenericDemo
{
    public static void main(String[] args)
    {
        InterImpl<Integer> i =new InterImpl<Integer>();
        i.show(4);
    }
}

 

泛型的限定

?通配符,也可以理解为占位符

泛型的限定:

为什么会出现?

因为要简便的传入父子类

?extends E:可以接收E类型或者E的子类型,上限

?super E:可以接收E类型或者E的父类型,下限

?均表示接收的对象

上限:

接收,用上限
<? extend T>

collection<? extend T> colle 用来接收对象,这里接收的对象是未知对象。
理解:只要是T或者T的子类,,就可以接收
就可以使用这个方法,如:T是Person,那么他的子类Student\Worker都可以使用这个方法

?是待定类型,T是已知类型

 

下限:

取出,用下限
<? super T>
理解,只要是T或者T的父类,就可以取出
取集合的类型,用集合的父类型接收,保证所有元素全能接收到。
比如我们给Person写一个比较器
我们用comparator<? super T> comp接收对象(接收的对象是已经写好的比较器)
如果接收的对象是Student ,那么只要我们有Student或者Student父类的比较器,我们就可以取出里面的方法来使用
这样就能保证我们对Person写了比较器,对Person以及Person的子类同样适用

?是已知类型,T是待定类型,T就是我们就是我们将要传入的对象,一般为已知类型的子类
 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值