由于泛型数组,变量不能初始化,查了查资料,感觉别人的好不可靠啊!自己搞了个方法搞定了,记一下! 直接上代码:我们的目标是构造一个栈,基本的三个功能,push,pop,peek. ###code
package Book;import java.lang.reflect.Array;import java.security.PrivateKey;/** * Created by pinker on 17-3-18. */public class MyStack{ // private T t; private T[] ele; private int cursor; private Class clazz; public MyStack(Class clazz) { this(clazz, 5); } public MyStack(Class clazz, int size) { this.clazz = clazz; ele = (T[]) Array.newInstance(clazz, size); cursor = -1; } public void push(T t) { //自动扩容 if (cursor == ele.length - 1) { T[] temp = (T[]) Array.newInstance(clazz, ele.length * 2); for (int i = 0; i < ele.length; i++) temp[i] = ele[i]; ele = temp; } ele[++cursor] = t; } public T peek() { if (cursor < 0) { System.out.println("没有元素啦!"); return null; } return ele[cursor]; } public T pop() { if (cursor < 0) { System.out.println("没有元素啦!"); return null; } return ele[cursor--]; } public static void main(String[] args) { MyStack stack1 = new MyStack<>(Integer.class); MyStack stack2 = new MyStack<>(String.class); stack1.push(1); stack1.push(2); stack1.push(3); stack1.push(4); stack1.push(5); stack1.push(6); stack1.push(7); stack1.push(8); stack2.push("HS"); stack2.push("YS"); stack2.push("ZS"); stack2.push("DS"); System.out.println(stack1.peek()); System.out.println(stack1.pop()); System.out.println(stack1.peek()); System.out.println(stack2.peek()); System.out.println(stack2.pop()); System.out.println(stack2.peek()); }}
###result
887DSDSZS
###自己想了想,如果泛型能在内部搞定,那么多API也就不会让我们传这种Class这种具体的对象类型了。此猜想留待以后看源码解决。
#泛型的类与方法之间的关系小记:
public class GenericTypeDemo{ public T test(T... a) { return a[a.length - 2]; } public static void main(String[] args) { Object obj = new GenericTypeDemo ().test("123", 0, "HS"); System.out.println(obj.getClass() + "-->" + obj); }}
class java.lang.Integer-->0
我们分析一下这段代码,类的泛型T我们规定为String,是不是意味着方法的泛型T也是String了呢?我们返现不是String,因为方法前面也声明了<T>,故我们能看到最后的结果是Integer.
- 泛型方法有自己的类型参数,泛型类的成员方法使用的是当前类的类型参数。
- 方法中有<T> 是泛型方法;没有的,称为泛型类中的成员方法
###如果限制只有特定某些类可以传入T参数,那么可以对T进行限定
//我们知道final类不可继承,在继承机制上class SomeString extends String是错误的, // 但泛型限定符使用时是可以的:,只是会给一个警告 public void test() { Test demo = new Test<>(); } class Test { } interface Parent { void say(); } class child1 implements Parent { @Override public void say() { System.out.println("i am child1"); } } class child2 extends child1 implements Comparable { @Override public int compareTo(Object o) { System.out.println("i am in compare method"); return 0; } @Override public void say() { System.out.println("i am child2"); } }
泛型擦除时:有多个限定符的,替换为第一个限定类型名。如果引用了第二个限定符的类对象,编译器会在必要的时候进行强制类型转换
#泛型的约束和限制 ##不能使用8个基本类型实例化类型参数 原因在于类型擦除,Object不能存储基本类型: byte,char,short,int,long,float,double,boolean ##类型检查不可使用泛型
if(aaa instanceof Pair){}//errorPair p = (Pair ) a;//warnPair p;Pair i;i.getClass()==p.getClass();//true
###泛型数组(见本博文上面),有一个特例是方法的可变参数,虽然本质上是数组,却可以使用泛型. ###不能实例化泛型对象 若要实例化泛型对象,必须传入Class<T> t参数,调用t.newInstance()。
publicvoid test3(Class t) { E obj = null; try { obj = t.newInstance(); } catch (InstantiationException e) {//实例化异常 e.printStackTrace(); } catch (IllegalAccessException e) {//非法访问异常 e.printStackTrace(); } System.out.println(obj.getClass()); }
class java.lang.String
可以看出泛型的实例化和数组的有的一比! ##泛型类的静态域中不能使用泛型类型;静态的泛型方法可以使用泛型类型 ##不能泛型重载 setName(T t)和setName(String t)不能同时存在!