java泛型

为什么有泛型?

早期的Object类可以接受任意的对象类型,但是在实际使用中会有类型转换问题。也就存在了安全隐患

class Demo02{

    //早期我们使用Object表示任意类型
    private Object object;

    public Object getObject(){
        return this.object;
    }

    public void setObject(Object object){
        this.object = object;
    }
}

public class Demo {
    public static void main(String[] args) {

       //正常使用
        Demo02 demo02 = new Demo02();
        demo02.setObject(new Integer(19));
        Integer i = (Integer)demo02.getObject();
        System.out.println("年龄是:" + i +"岁。");

        /**
         * 向上转型是没有问题的,但是向下转型就会隐含类型转换问题了
         * 也就是说这样的程序并不安全。
         */
        Demo02 d = new Demo02();
        d.setObject(new String("hello"));
        //我们传入的是Integer类型,但是我们转换为String类型,编译器虽然不报错,但是运行就会出错
        Integer i2 = (Integer)d.getObject();  //ClassCastException异常
        System.out.println("年龄是:" + i2 +"岁。");        
    }
}

所以JDK5后java提供了泛型来解决这个问题。

泛型类的使用


//尖括号里面的字母可以随便写
class Demo02<T>{

    private T t;

    public T  getObject(){
        return this.t;
    }

    public void setObject(T t){
        this.t = t;
    }
}


public class Demo{
    
    public static void main(String[] args) {

        //正常使用
        Demo02<Integer> demo02 = new Demo02();
        demo02.setObject(new Integer(19));
        Integer i = demo02.getObject();
        System.out.println("年龄是:" + i +"岁。");

        /**
         * 我们已经固定了传入的类型必须为Integer类型
         * 此时再传入String类型的话就会编译报错了
         */
        Demo02<Integer> d = new Demo02();
        d.setObject(new String("hello"));  //编译报错
        Integer i2 = (Integer)d.getObject(); 
        System.out.println("年龄是:" + i2 +"岁。");

    }
}

泛型方法

有这样一个需求,我们想要使用一个方法名输出不同的类型的数据,那么就需要重载这个方法,要是我的需求需要有几十个数据类型,那么我就需要写几十个重载的方法,这样的代码太臃肿了。如下:

public class Demo{

    public static void main(String[] args) {
        Demo02 d1 = new Demo02();
        d1.show("hello");  //输出字符串
        d1.show(100);  //输出数字
        d1.show(99.99);  //输出小数
    }
}

class Demo02{

    /**
     * 我们想要使用一个方法名输出不同的类型就需要重载这个方法
     * */

    //输出字符串
    public void show(String str){
        System.out.println(str);
    }

    //输出数字
    public void show(int i){
        System.out.println(i);
    }

    //输出小数
    public void show(double d){
        System.out.println(d);
    }
	
	// 输出其他类型......
}

所以我们可以使用泛型方法来解决这个问题:

class Demo02{
    /**
     * 只需要写一个方法即可,需要注意的是如果类上面不写泛型的话
     * 在方法的括号里面写泛型那么就需要在返回值类型的前面加 <泛型名>
     * */
    //输出
    public <T> void show(T t){  //需要在返回值前面加 <T> ,T是你的泛型名
        System.out.println(t);
    }
}

public class Demo{

    public static void main(String[] args) {
        Demo02 d1 = new Demo02();
        d1.show("hello");  //输出字符串
        d1.show(100);  //输出数字
        d1.show(99.99);  //输出小数
    }
}

泛型接口
接下来我们看看泛型接口:
定义一个泛型接口:

public interface Demo<T>{
    void show(T t); 
}

通过类去实现这个泛型接口的时候指定泛型T的具体类型。
指定具体类型为String:

public class DemoImpl implements Demo<String>{

    @Override
    public void show(String t) {
        System.out.println(t);
    }

   public static void main(String[] args) {
        Demo<String> demo = new DemoImpl(); //明确指定为String类型
        demo.show("hello");
        demo.show(100);  //这里我们传入int类型就会遍编译报错了
    }
}

上面直接指定泛型的数据类型,这种方式并不常见,最常见的是使用的时候才指定泛型的数据类型,如下,还是实现Demo接口:


/**
 * 这里需要注意的是,如果你想在使用的时候才指定泛型的数据类型
 * 那么就必须在实现接口类上面也加上泛型的名字,
 * 且泛型接口不能直接指定泛型的数据类型
 * */
public class DemoImpl<T> implements Demo<T>{

    @Override
    public void show(T t) {
        System.out.println(t);
    }

    public static void main(String[] args) {
        
        /**
         * 实现类的数据类型要和泛型接口的数据类型一致
         * 否则会报错
         * */
        Demo<String> demo = new DemoImpl<String>();
        demo.show("hello");

        Demo<Integer> demo2 = new DemoImpl<Integer>();
        demo2.show(100);
        
        /**
         *这里还需要注意就是如果右边的泛型接口不写数据类型的话,并不会报错
         *但是你要是传入其他的数据类型他都能正常输出,那样的话就达不到我们想要的效果了
         */
        Demo demo3 = new DemoImpl<String>();  //不指定泛型接口Demo的数据类型
        demo3.show("hello"); 
        demo3.show(1000);  //虽然实现类固定了为String类型但是此处编译不报错,运行也能正常输出
    }
}

泛型高级(通配符)
<?> 表示任意类型,如果没有明确规定就是Object类型以及任意的java类型
<? extends E> 向下限定,E及其子类
<? super E> 向上限定,E及其父类

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值