首先用Object实现一个简单的堆栈实例:
package Item29;import java.util.Arrays;import java.util.EmptyStackException;/*** @author: qujundong* @date: 2020/11/29 上午9:36* @description:*/public class StackObject {private Object[] elements;private int size = 0;private static final int DEFAULT_INITIAL_CAPACITY = 16;public StackObject(){elements = new Object[DEFAULT_INITIAL_CAPACITY];}public void push(Object e){ensureCapacity();elements[size ++] = e;}public Object pop(){if(size == 0)throw new EmptyStackException();Object result = elements[--size];elements[size] = null;return result;}private boolean isEmpty(){return size == 0;}private void ensureCapacity(){if(elements.length == size){elements = Arrays.copyOf(elements, 2 * size + 1);}}@Overridepublic String toString() {return "StackObject{" +"elements=" + Arrays.toString(elements) +", size=" + size +'}';}public static void main(String[] args) {StackObject stack = new StackObject();stack.push(2);stack.push(4);stack.push("SS");//客户端使用的时候很容易出现类型转换上的问题,并且编译找不出错误//Integer s = (Integer)stack.pop()System.out.println(stack.pop());System.out.println(stack);}}/*SSStackObject{elements=[2, 4, null, null, null, null, null, null, null, null, null, null, null, null, null, null], size=2}*/
上述代码可以存入任意类型,这有一个坏处,如果客户端进行了错误的类型转换,在编译期无法报错,这是不使用泛型的坏处,下面尝试使用泛型,但是无法新建泛型数组,有两种解决办法,分别尝试。
1. 新建Object数组,声明泛型数组引用,通过强转将Object转成E
package Item29;import java.util.Arrays;import java.util.EmptyStackException;/*** @author: qujundong* @date: 2020/11/29 上午9:48* @description:*/public class StackGeneric<E> {private E[] elements ;private int size = 0;private static final int DEFAULT_INITIAL_CAPACITY = 16;//因为使用类型转化会出现警告,但是确认没什么问题,所以取消未受检警告@SuppressWarnings("unchecked")public StackGeneric(){//因为无法声明泛型数组,因此使用Object[]然后转化一下类型为E[]elements = (E[])new Object[DEFAULT_INITIAL_CAPACITY];}public void push(E e){ensureCapacity();elements[size ++] = e;}public E pop(){if(size == 0)throw new EmptyStackException();E result = elements[--size];elements[size] = null;return result;}private boolean isEmpty(){return size == 0;}private void ensureCapacity(){if(elements.length == size){elements = Arrays.copyOf(elements, 2 * size + 1);}}@Overridepublic String toString() {return "StackObject{" +"elements=" + Arrays.toString(elements) +", size=" + size +'}';}public static void main(String[] args) {StackGeneric<Integer> stack = new StackGeneric<>();stack.push(2);stack.push(4);System.out.println(stack.pop());System.out.println(stack);}}
上述代码出现警告,因此用@SuppressWarnings(“unchecked”)解决
注: StackGeneric.java使用了未经检查或不安全的操作。注: 有关详细信息, 请使用 -Xlint:unchecked 重新编译。
2. 新建Object数组和引用
package Item29;import java.util.Arrays;import java.util.EmptyStackException;/*** @author: qujundong* @date: 2020/11/29 上午9:48* @description:*/public class StackGeneric2<E> {private Object[] elements ;private int size = 0;private static final int DEFAULT_INITIAL_CAPACITY = 16;public StackGeneric2(){elements = new Object[DEFAULT_INITIAL_CAPACITY];}public void push(E e){ensureCapacity();elements[size ++] = e;}@SuppressWarnings("unchecked")public E pop(){if(size == 0)throw new EmptyStackException();//用泛型强转E result = (E)elements[--size];elements[size] = null;return result;}private boolean isEmpty(){return size == 0;}private void ensureCapacity(){if(elements.length == size){elements = Arrays.copyOf(elements, 2 * size + 1);}}@Overridepublic String toString() {return "StackObject{" +"elements=" + Arrays.toString(elements) +", size=" + size +'}';}public static void main(String[] args) {StackGeneric2<Integer> stack = new StackGeneric2<>();stack.push(2);stack.push(4);System.out.println(stack.pop());System.out.println(stack);}}
上述代码也会出现警告问题,不过出现在pop函数中,因此依然需要用@SuppressWarnings(“unchecked”)消除警告。
总结:使用泛型比在客户端进行类型转换要安全的多,并且也可以更早的发现错误,在编译期就解决。
