当前位置:   article > 正文

Java泛型的初步认识与使用_泛型通配符来接收返回的数据

泛型通配符来接收返回的数据

什么是泛型

概念:参数化类型、类型安全的集合,强制集合元素的类型必须一致

特点

  • 编译时即可检查,而非运行时抛出异常
  • 访问时,不必类型转换
  • 不同泛型之间引用不能相互赋值,泛型不存在多态
  • 不能包含仅使用泛型作为参数的重载方法

泛型的好处:

  • 提高代码的重用性
  • 防止类型转换异常,提高代码的安全性

泛型类

就比如ArrayList类,可以传入任何类型的数据,但是为了规范,我们需要指明数据的类型ArrayList< String>,这样ArrayList就只能存入String类型的数据了

我们可以自定义泛型类,然后在类的内部使用这个类型的数据

/**
 * 泛型类。
 * @author 张宝旭
 */
public class Generic<T> {
    // 定义泛型属性
    private T t;

    // 返回值为T,参数为T
    public T show(T t) {
        System.out.println(t);
        return t;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
/**
 * @author 张宝旭
 */
public class GenericTest {
    public static void main(String[] args) {
        // 定义一个参数为String类型的对象
        Generic<String> generic1 = new Generic<>();
        generic1.show("Hello");

        // 定义一个参数为Integer类型的对象
        Generic<Integer> generic2 = new Generic<>();
        generic2.show(125);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

泛型方法

比如ArrayList类中的add()方法,我们可以添加任意类型的数据到列表中,但是内部如果要是使用重载来实现,那就要定义很多个方法,int、float、String、Double等待类型的,如果使用泛型,那么只需要定义一个泛型方法,就可以实现此功能,传入任意类型的数据了。

public class Generic2 {
    /**
     * 泛型方法
     * @param t 参数为泛型
     * @param <T> 泛型类型的方法
     * @return 返回类型为泛型
     */
    public static <T> T show(T t) {
        System.out.println(t);
        return t;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
// 测试
Generic2.show("OK");
  • 1
  • 2

泛型接口

public interface GenericInterface<T> {
    T print(T t);
}
  • 1
  • 2
  • 3

实现类也声明为泛型

public class Generic3<T> implements GenericInterface<T>{
    @Override
    public T print(T t) {
        System.out.println(t);
        return t;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

实现类声明为指定类型

public class Generic3<String> implements GenericInterface<String>{
    @Override
    public String print(String string) {
        return string;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

泛型上下限

?代表任意类型

public class GenericTest {
    public static void main(String[] args) {
        Generic<Person> generic1 = new Generic<>();
        show(generic1);
        Generic<String> generic2 = new Generic<>();
        show(generic2);
    }
    public static void show(Generic<?> generic) {
        generic.show();
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

上限

? extends Person 代表只要是Person类型,或者是Person的子类都可以

public class GenericTest {
    public static void main(String[] args) {
        Generic<Person> generic1 = new Generic<>();
        show(generic1);
        Generic<Student> generic2 = new Generic<>();
        show(generic2);
    }
    public static void show(Generic<? extends Person> generic) {
        generic.show();
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

下限

? super Person 代表只要是Person类型,或者Person的父类都可以

public class GenericTest {
    public static void main(String[] args) {
        Generic<Person> generic1 = new Generic<>();
        show(generic1);
        Generic<Object> generic2 = new Generic<>();
        show(generic2);
    }
    public static void show(Generic<? super Person> generic) {
        generic.show();
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

【强制】泛型通配符<? extends T>来接收返回的数据,此写法的泛型集合不能使用 add方法, 而<? super T>不能使用get方法,两者在接口调用赋值的场景中容易出错。


泛型擦除

反编译查看源码

可以看到类的泛型都被去掉了,而这就意味着在运行的时候,JVM会将它们视为同一类型

public class GenericTest
{

	public GenericTest()
	{
	}

	public static void main(String args[])
	{
		Generic generic1 = new Generic();
		show(generic1);
		Generic generic2 = new Generic();
		show(generic2);
	}

	public static void show(Generic generic)
	{
		generic.show();
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/凡人多烦事01/article/detail/471738
推荐阅读
相关标签
  

闽ICP备14008679号