泛型

本文详细介绍了Java中的泛型概念,包括泛型的利弊、如何在类、方法和接口中使用泛型,以及泛型通配符的两种基本使用和高级使用情况。通过示例代码展示了泛型在实际编程中的应用,帮助读者理解如何提升代码的类型安全性并减少类型转换的麻烦。
摘要由CSDN通过智能技术生成

泛型

概念

泛型是一种未知的数据类型,当我们不知道使用什么数据类型的时候,可以使用泛型,也可以看作是一个变量,用来接收数据类型。(E e:Element元素,T t:Type类型)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-V4O5ml7k-1620467634842)(E:\学习文档\JavaWeb\img\泛型\1619248400769.png)]

使用泛型的利与弊

好处:

  1. 避免了类型转换的麻烦,存储的是什么类型,取出的就是什么类型
  2. 把运行期异常(代码运行之后会抛出的异常),提升到了编译期(写代码的时候会报错)

弊端:

​ 泛型是什么类型,只能存储什么类型的数据

泛型的使用

在类中使用

package com.fanxing;

public class GenericClass <E>{
    private E name;
    public E getName(){
        return this.name;
    }

    public void setName(E name) {
        this.name = name;
    }
}
package com.fanxing;

public class GenericClassTest {
    public static void main(String[] args) {
        GenericClass<Boolean> genericClass = new GenericClass();
        genericClass.setName("aaa");//这里就是把运行期的错误放在编译期的完美体现,只能是Boolean类型
        System.out.println(genericClass.getName());
    }
}
//如果不写类型的时候,就是Object

在方法中使用

定义含有泛型的方法:泛型定义在方法的修饰符和返回值类型之间
格式:修饰符 <泛型> 返回值类型 方法名(参数列表(使用泛型)){
方法体
}
含有泛型的方法,在调用方法的时候确定泛型的数据类型。传递什么类型的参数,泛型就是什么类型。

package com.fanxing;
public class GenericClass {
    public <E> E method(E type){
        return type;
    }
}
package com.fanxing;
public class GenericClassTest {
    public static void main(String[] args) {
        GenericClass genericClass = new GenericClass();
        String str = genericClass.method("aaa");
        System.out.println(str);
    }
}
//在这里传入的是什么值,返回的就是什么值

含有泛型的接口

方式一:

含有泛型的接口,第一种使用方式:定义接口的实现类,实现接口,指定接口的泛型,

public interface Iterator<E>{}

Scanner类实现了Iterator接口,并指定接口的泛型为String,所有重写的next方法泛型默认就是String

public final class Scanner implements Iterator<String>{
	@Override
	public void method(String s){
		System.out.println(s);
	}
}

例:

package com.fanxing;

public interface GenericInterface<T> {
    boolean add(T t);
    T get(T type);
}

package com.fanxing;
public class GenericInterfaceImpl implements GenericInterface<String>{
    @Override
    public boolean add(String s) {
        return false;
    }

    @Override
    public String get(String type) {
        return null;
    }
}

方式二:

含有泛型的接口第二种使用方式:接口使用什么泛型,实现类就使用什么泛型,类跟着接口走就相当于定义了一个含有泛型的类,创建对象的时候确定泛型的方法

package com.fanxing;
public interface GenericInterface<T> {
    boolean add(T t);
    T get(T type);
}
package com.fanxing;
public class GenericInterfaceImpl<I> implements GenericInterface<I>{
    @Override
    public boolean add(I i) {
        return false;
    }
    @Override
    public I get(I type) {
        return null;
    }
}

泛型通配符

当使用泛型类型或者接口时,传递的数据中,泛型类型不确定,可以通过通配符<?>表示,但是一旦使用泛型的通配符后,只能使用Object类中的共性方法,集合中元素自身的方法无法使用。

通配符基本使用

泛型的通配符:不知道使用什么类型来接收的时候,此时可以使用?,?表示未知通配符此时只能接受数据,不能往该集合中存储数据。

package com.fanxing;
import java.util.ArrayList;
public class GenericLable {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            list.add("name"+i);
        }
        ArrayList<Integer> list1 = new ArrayList<>();
        getElement(list);
    }
    public static void getElement(ArrayList<?> aryList){
        for (String o : aryList) {//这里会报错因为如果使用了通配符,就只能使用Object类型,不能再使用其他类型了
            System.out.println(o);
        }
    }
}

通配符的高级使用------受限泛型

之前设置泛型的时候,实际上是可以任意设置的,只要是类就可以设置。但是在JAVA的泛型中可以指定一个泛型的上限和下限。

泛型的上限
  • 格式:类型名称<? extends 类>对象名称
  • 意义:只能接收该类型及其子类
泛型的下限
  • 格式:类型名称<? super 类> 对象名称
  • 意义:只能接收该类型及其父类型

比如:现已知Object类,String类,Number类,Integer类,其中Number是Integer的父类

package com.fanxing;

import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Collection;

public class GenericLable{
    public static void main(String[] args) {
        ArrayList<Number> list1 = new ArrayList<>();
        ArrayList<Object> list2 = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            list1.add(i);
            list2.add("i"+i);
        }
        getElement1(list1);
        getElement2(list2);
    }
    public static void getElement1(Collection<? extends Number> coll){
        //extends只能写Number类型或者Number类型的子类型
        for (int i = 0; i < coll.size(); i++) {
            System.out.println(coll);
        }
    }
    public static void getElement2(Collection<? super Number> coll){
        //super只能写Number类型或者Number类型的父类型
        for (int i = 0; i < 10; i++) {
            System.out.println(coll);
        }
    }
}

}
}
public static void getElement2(Collection<? super Number> coll){
//super只能写Number类型或者Number类型的父类型
for (int i = 0; i < 10; i++) {
System.out.println(coll);
}
}
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值