对java泛型的理解

时间:2022-12-01 21:11:54

  正确的应用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的超类。