泛型

xiaoxiao2025-04-19  14

泛型

Java集合有一个缺点就是把一个对象”丢进去“之后。集合就会”忘记“这个对象的数据类型,当再次取出该对象时,该对象的变异类型就会变成Object类型(运行时类型不变)。 这样设计的原因就是为了提高集合的通用性,但是会带来下面两个问题: 1.集合元素类型无限制,可能引起异常,不同的对象都可以放入集合,就会以引起异常。 2.由于集合对象放入集合时,集合对象就会丢失对象的状态信息,集合只知道它盛装的是Object,因此取出集合元素后通常还需要进行强制类型转换。不仅提高编程复杂度,而且可能引起ClassCastException。

import java.util.ArrayList; import java.util.List; public class ListErr { public static void main(String[] args) { //创建一个只保存字符串的List集合 List strList = new ArrayList(); strList.add("Home"); strList.add("School"); //向集合中加入一个Integer类型 strList.add(12); //遍历集合 for (Object str : strList){ System.out.println((String)str); } } }

这样就会出现一个ClassCastException异常 如果使用泛型的话就不会出现上述异常,如果你非要向集合中加入一个Integer类型时就会直接编译报错,修改代码如下

import java.util.ArrayList; import java.util.List; public class ListErr { public static void main(String[] args) { //创建一个只保存字符串的List集合 List<String> strList = new ArrayList<>(); strList.add("Home"); strList.add("School"); //向集合中加入一个Integer类型 //strList.add(12);//编译报错 for (String str : strList){ System.out.println(str); } } }

泛型语法

泛型的语法如下 在Java7以前,如果使用带泛型的接口、类的定义的变量,那么构造器创建对象时构造器后必须要加泛型,这就显得有点多余了,所以在Java7以后构造器后的泛型可以省略。

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

泛型接口、类

泛型类 当一个类要操作的引用数据类型不确定的时候,可以给该类定义一个形参。用到这个类的时候,通过传递类型参数的形式,来确定要操作的具体的对象类型。在JDK1.5之前,为了提高代码的通用性,通常把类型定义为所有类的父类型:Object,这样做有两大弊端:

在具体操作的时候要进行强制类型转换;这样还是指定了类型,还是不灵活,对具体类型的方法未知且不安全。 如下: public class MyClass { private Object obj; public Object getObj() { return obj; } public void setObj(Object obj) { this.obj = obj; } }

但是如果我们用泛型来定义的话就不会有这些问题

public class MyClass2<M> { private M m; public M getM() { return m; } public void setM(M m) { this.m = m; } }

泛型接口 将泛型原理用于接口实现中,就是泛型接口。 泛型接口的格式:泛型接口格式类似于泛型类的格式,接口中的方法的格式类似于泛型方法的格式。 定义一个泛型接口

public interface MyInterface <T>{ public T read(T t); }

使用这个泛型接口

public class Test4 implements MyInterface<String>{ public static void main(String[] args) { Test4 t = new Test4(); System.out.println(t.read("Hello interdace")); } @Override public String read(String str) { return str; } }

泛型方法

泛型方法也是为了提高代码的重用性和程序安全性。编程原则:尽量设计泛型方法解决问题,如果设计泛型方法可以取代泛型整个类,应该采用泛型方法。 泛型方法的格式:类型变量放在修饰符后面和返回类型前面, 如:public static E getMax(T… in)

public class Max { public static void main(String[] args) { System.out.println(getMax(1,2)); System.out.println(getMax(0.3,0.5)); } public static<T> T getMax(T t1,T t2){ return t1.equals(t2)? t1: t2; } }

泛型通配符

当操作的不同容器中的类型都不确定的时候,而且使用的元素都是从Object类中继承的方法,这时泛型就用通配符“?”来表示。 泛型的通配符:“?” 相当于 “? extends Object”

import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.Iterator; public class AllCollectionIterator { public static void main(String[] args) { HashSet<String> s1 = new HashSet<String>(); s1.add("sss1"); s1.add("sss2"); s1.add("sss3"); ArrayList<Integer> a1 = new ArrayList<Integer>(); a1.add(1); a1.add(2); a1.add(3); a1.add(4); printAllCollection(a1); System.out.println("-------------"); printAllCollection(s1); } public static void printAllCollection(Collection<?> c){ Iterator<?> iter = c.iterator(); while (iter.hasNext()) { System.out.println(iter.next().toString()); } } }

泛型限定 泛型限定就是对操作的数据类型限定在一个范围之内。限定分为上限和下限。 向上限定:? extends E 接收E类型或E的子类型 向下限定:? super E 接收E类型或E的父类型 限定用法和泛型方法,泛型类用法一样,在“<>”中表达即可。 一个类型变量或通配符可以有多个限定,多个限定用“&”分隔开,且限定中最多有一个类,可以有多个接口;如果有类限定,类限定必须放在限定列表的最前面。如:T extends MyClass1 & MyInterface1 & MyInterface2 !

import java.util.Calendar; import java.util.GregorianCalendar; public class GenericGetMax { public static void main(String[] args) { String[] inArrStr = {"haha", "test", "nba", "basketball"}; System.out.println(GetMax.findMax(inArrStr).toString()); Integer[] inArrInt = {11, 33, 2, 100, 101}; System.out.println(GetMax.findMax(inArrInt)); GregorianCalendar[] inArrCal = { new GregorianCalendar(2016, Calendar.SEPTEMBER, 22), new GregorianCalendar(2016, Calendar.OCTOBER, 10)}; System.out.println(GetMax.findMax(inArrCal).toZonedDateTime()); } } class GetMax { @SafeVarargs public static <T extends Comparable> T findMax(T... in) { T max = in[0]; for (T one : in) { if (one.compareTo(max) > 0) { max = one; } } return max; } }
转载请注明原文地址: https://www.6miu.com/read-5028608.html

最新回复(0)