正确的应用java泛型的特性可以更好的实现编程的开闭原则(对扩展开放,对修改关闭),这得益于java泛型提供的在程序运行时获取对象声明类型的特性。
静态语言的特性是在程序编译前进行声明,这样程序在编译期就能很方便的获取变量的类型。动态语言提供了程序在运行时获取对象声明类型的特性,具有更好的扩展性,java是一门动态语言。
一个对象可以被理解为一个变量的实例。一个对象能够被加载的前提是有确定的声明,同时只要获取到对象就可以获取到确定的声明类型。所以,泛型编程必须满足以下两点:
1,程序必须在运行期能够得到确定的声明。
2,获取对象之后才可以获取到对象的声明类型。
下面给出三种声明方式,以及相对应的运行阶段获取对象类型的方法。The Code Shows Everything, Let's go~
第一类:简单声明
public class Bean<T> { T t; public T getT() { return t; } public void setT(T t) { this.t = t; } }
第二类:父类声明
import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; public class ExtendGeneral<T> { Class<T> t; public void aaa(){ Type superClassGenricType = getSuperClassGenricType(getClass(), 0); System.out.println(getClass()); System.out.println(t); t = (Class<T>) superClassGenricType; System.out.println(t); } public static Type getSuperClassGenricType(Class clazz, int index) { //返回表示此 Class 所表示的实体(类、接口、基本类型或 void)的直接超类的 Type。 Type genType = clazz.getGenericSuperclass(); //返回表示此类型实际类型参数的 Type 对象的数组。 Type[] params = ((ParameterizedType) genType).getActualTypeArguments(); return params[index]; } }
public class Test1 extends ExtendGeneral<String>{ }
第三类,接口声明
public interface InterGeneral<A, B> { <B> B aaa(A a); }
import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.HashMap; public class Test2 implements InterGeneral<String, HashMap>{ @Override public HashMap aaa(String a) { Type[] genericSuperclass = getClass().getGenericInterfaces(); ParameterizedType type = (ParameterizedType)genericSuperclass[0]; Type[] actualTypeArguments = type.getActualTypeArguments(); System.out.println(actualTypeArguments[0]); System.out.println(actualTypeArguments[1]); return null; } }
main方法:
public class Main { public static void main(String[] args) { System.out.println("简单声明泛型:"); Bean<String> b = new Bean<String>(); b.setT("333"); String t = b.getT(); System.out.println(t); System.out.println("继承声明泛型:"); Test1 t1 = new Test1(); t1.aaa(); System.out.println("接口声明泛型:"); Test2 t2 = new Test2(); t2.aaa(""); } }
输出结果:
简单声明泛型: 333 继承声明泛型: class com.asiainfo.base.T.Test1 null class java.lang.String 接口声明泛型: class java.lang.String class java.util.HashMap
Type类是一个接口,是所有Class的超类。