简单了解java中的泛型

泛型

1、泛型含义

泛型是一种类型参数,专门用来保存类型用的。

例如ArrayList< E>,这个E就是所谓的泛型了。使用ArrayList时,只要给E指定某一个类型,里面所有用到泛型的地方都会被指定对应的类型。

2、使用泛型的好处

不用泛型带来的问题

集合若不指定泛型,默认就是Object。存储的元素类型自动提升为Object类型,获取元素时得到的都是Object,若要调用特有的方法需要转型,这样会带来很多麻烦。

使用泛型带来的好处

可以在编译时对类型做出判断,避免不必要的类型转换操作,精简代码,也避免了因为类型转换导致的错误。

注意:泛型在代码运行时,泛型会被擦除,我们可以实现在代码运行过程中添加其他类型的数据到集合中,所以泛型是使用在编写时期的技术方式。

3、泛型的使用

3.1、泛型类

  • 定义格式

    在类型名后面加上一对尖括号,里面定义泛型。一般使用一个英文大写字母,如果有多个泛型使用逗号隔开。

    public class 类名<泛型>{
        //类型内部,可以把泛型当作是某一种类型使用
    }
    
  • 泛型的确定

    当我们不确定类中的某个属性使用什么类型时,可以用泛型表示

    public class 类名<TG>{
    	private TG 变量;
    }
    

    在我们创建泛型类对象时,明确泛型类型

    泛型类<Double> 对象 = new 泛型类<Double>();
    //此时泛型类中的成员变量是Double类型
    
  • 代码示例

//当不确定类中成员变量使用什么类型时可以用泛型来表示
class TgClass<T>{
    private T demo;

    public T getDemo() {
        return demo;
    }

    public void setDemo(T demo) {
        this.demo = demo;
    }
}

public class Demo1 {
    public static void main(String[] args) {
        //创建对象,指定泛型类型为Double
        TgClass<Double> d = new TgClass<Double>();

        d.setDemo(2319848.89901);
        System.out.println(d.getDemo());
    }
}

3.2、泛型接口

  • 定义格式

    在接口名后面加上一对尖括号,里面定义泛型。一般使用一个英文大写字母,如果有多个泛型使用逗号隔开。

    public interface 接口名<T>{
        
    }
    
  • 泛型确定

    当定义接口时,其内部方法中的参数或者返回值类型不确定时,就可以使用泛型代替了。

    比如这样

    public interface 泛型接口<T>{
        public void demo(T x);
    }
    

    可以在实现类,实现接口时,确定接口中的泛型的类型(情况一),如果实现类和接口不指定具体类型,继续使用泛型指定含有泛型的类使用(情况二)。

    比如这样

    //情况一
    public class 子类 implements 泛型接口<String>{
        public void demo(String x){
            
        }
    }
    
    //情况二
    public class 子类<T> implements 泛型接口<T>{
        //方法重写
        public void demo(T a){
            
        }
    }
    子类<String> 对象 = new 子类<>();//创建子类对象时明确泛型的类型
    
  • 代码示例

定义父接口

public interface Father<T> {
    public void play(T x);
}

情况一

public class SonImp1 implements Father<Integer>{
    @Override
    public void play(Integer x) {
        System.out.println(x + "参数类型是Integer");
    }
}

public class Test1 {
    public static void main(String[] args) {
        SonImp1 sonImp1 = new SonImp1();

        sonImp1.play(999);
    }
}

情况二

public class SonImp2<T> implements Father<T>{
    @Override
    public void play(T x) {
        System.out.println(x + "参数类型是String");
    }
}

public class test2 {
    public static void main(String[] args) {
        SonImp2<String> sonImp2 = new SonImp2<>();

        sonImp2.play("哈哈哈");
    }
}

3.3、泛型方法

  • 语法格式

    修饰符号 <泛型> 返回值类型 方法名(泛型 参数1, 泛型 参数2,...){
        //方法体
    }
    
  • 泛型确定

    如果当前类没有声明泛型类,但该方法中的方法参数或者方法返回值不确定时,可以使用泛型类

    public <T> void demo(T x, Ty){
        
    }
    

    调用含有泛型的方法时,传入的数据其类型就是泛型的类型

4、泛型通配符

4.1、泛型通配符介绍

当我们对泛型的类型确定不了了,而想要表达的是任意类型,可以使用泛型通配符给定。符号就是一个问号“?”,表示任意类型,用来给泛型指定的一种通配符。

4.2、泛型统配符使用

泛型统配符搭配集合使用一般在方法的参数中比较常见。

我们可以来个示例:

假如有一个Person父类

public class Person {
    public int age;
    public String name;
}

Person有两个子类Student和Teacher,这时候我们需要创建一个集合,向这个集合中添加指定元素类型,那么我们可以这样做

ArrayList<Student> array = new ArrayList<>();
ArrayList<Teacher> array = new ArrayList<>();

那还有什么方式向集合中添加指定元素类型呢?这时候,有人可能会联想到多态,那么我们是不是还可以这样

ArrayList<Person> array = new ArrayList<Student>();

很遗憾,java中是不允许这样做的,java中的泛型没有多态这个概念,正确的做法是这样

//使用通配符
ArrayList<?> array = new ArrayList<Student>();

这样做有什么好处嘞?我们试想,现在有两个方法如下

public static void demoStu(ArrayList<Student> array){
    
}

public static void demoStu(ArrayList<Teacher> array){
    
}

假如两个方法中的操作相同,只是传递参数的类型有差别,这时候上面的代码就显得有些冗余了,那么这时候,统配符就可以解决此问题

public static void demoStu(ArrayList<?> array){
    
}

这样做之后,无论我们传递的参数是ArrayList< Student>类型,还是ArrayList< Teacher>类型,方法都能接收参数,不会发生报错。

5、受限泛型

受限泛型是指,在使用通配符的过程中,对泛型做了约束,给泛型指定类型时,只能是某个类型父类型或者子类型。

5.1、泛型的下限

只能是某一类型,及其父类型,其他类型不支持。

<? super 类型>
    
<? super 最小类型>
//?可以是最小类型也可以是父类型

5.2、泛型的上限

只能是某一类型,及其子类型,其他类型不支持。

<? extends 类型>
    
<? extends 最大类型>
//?可以是最大类型,也可以是子类型

5.3、代码示例

4.2中的示例方法我们现在还能这样写

public static void demo(ArrayList<? extends Person> array){

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值