初学者学Java(二十)

泛型是JDK5.0引入的新特性,旨在提高代码的安全性和质量。它避免了强制类型转换,增强了编译时的类型检查,防止了运行时的ClassCastException。泛型通过规定数据类型,使得集合在编译阶段就能进行类型检查,减少了类型转换异常。同时,泛型简化了代码,例如在创建多个类似get(), set()方法的类时,可以使用一个泛型类代替,减少了重复代码。此外,通过使用extends关键字,还可以限制泛型类型的实例化范围。" 89466240,7474372,TensorFlow 2.0 Docker环境搭建指南,"['环境搭建', '深度学习', 'TensorFlow', 'GPU支持', '容器化']

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

                   泛型(Generics)

        泛型是作为jdk5.0的新特性出现的,在没有泛型之前,我们使用集合类的时候,不管存的是什么类型,返回的都是Object类型,用的时候需要强制类型转换。但如果我们存的如果是String类型的变量,却强制类型转换为Integer类型,这样在编译的时候并不会报错,因为我们是将一个Object类型的转换为Integer类型,而系统在编译时并不知道我们存如的是String类型,但在执行的时候会出现异常。

为了解决这个问题我们引入了泛型。

              泛型的使用方法

1.规定数据类型,提高代码的安全性(以ArrayList为例)

在学泛型以前我们使用ArrayList会产生一个警告。

例:

package test;

import java.util.*;

public class GenericsTestOne {

    public static void main(String[]args) {

        List listOne = newArrayList();

    }

}

警告是这么写的:

         ArrayList 是原始类型。应该将对通用类型ArrayList<E> 的引用参数化

后面的<E>就是泛型的一种表现形式。

他说没有用泛型进行引用参数化,如果不进行参数化会引起什么错误呢。

下面我写这么几行代码:

listOne.add("冶近玮");

Integer int1 =(Integer)listOne.get(0);

这在编译的时候并不会报错,因为集合get()方法返回的是一个Object类型的,在编译的时候编译器并不知道我在内部存放的是一个String类的变量,所以这么写不会报错。但在执行的时候他就会知道内部是String类,所以会给我报一个异常,是这么写的:

 java.lang.ClassCastException: java.lang.Stringcannot be cast to java.lang.Integer

也就是说String类型的变量不能转换成Integer类型。

而我们的泛型就是解决这个问题的,如果使用泛型,只要代码在编译时没有出现警告,就不会遇到运行时ClassCastException。下面我们看看泛型怎么使用,和使用后的效果。还是上面这个程序我只修改 一行:

 List<String> listOne = new ArrayList<String>();

这时在我们把String强制转换为Integer的那行,他就不会不痛不痒的给个警告,而会直接给出错误:

不能从 String 强制类型转换为Integer

所以泛型可以提高代码的安全性。

2.泛型可以提高代码的质量

在以前,我们想要写一个类,类中有一个字符串变量,get(),set(),构造方法。还有一个类,类中有一个Integer变量,get(),set(),构造方法。只能这么写:

class MyTestOne

{

    private String string1;

    public String getString1() {

        return string1;

    }

    public void setString1(String string1) {

        this.string1 = string1;

    }

    public MyTestOne(String string1)

    {

        this.string1 = string1;

    }

}

class MyTestTwo

{

    private Integer integer1;

    public Integer getString1() {

        return integer1;

    }

    public void setString1(Integer integer1) {

        this.integer1 = integer1;

    }

    public MyTestTwo(Integer integer1)

    {

        this.integer1= integer1;

    }

}

这只是两个类呢,要是20个呢?还不得累死。但是我们学了泛型就可以这么写:

class MyTest<T>

{

    private T o1;

    public T getString1() {

        return o1;

    }

    public void setString1(T o1) {

        this.o1 = o1;

    }

    public MyTest(To1)

    {

        this.o1 = o1;

    }

}

如果你想要一个String型的你就这么声明:

MyTest<String>myTest1 = new MyTest<String>("冶近玮");

如果你想要一个Integer型的你就这么声明:

 

MyTest<Integer> myTest2= new MyTest<Integer>(new Integer(1));

效果和上面写两个类效果是一样的,来20个类,不过就是多20个声明罢了,会大大的减少代码量。

而且在定义泛型类别时,预设可以使用任何的类型来实例化泛型类型中的类型,但是如果想要限制使用泛型类别时,只能用某个特定类型或者是其子类型才能实例化该类型时,可以在定义类型时,使用extends关键字指定这个类型必须是继承某个类,或者实现某个接口。其实我们上面写的<T>是等价于下面这个式子。

<T       extends         Object>

就算两个类名相同的变量,泛型不同也不能互相赋值,如上例的myTest1和myTest2就不能互相赋值,否则报错。

关于泛型我就说这些了。

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值