Guice TypeLiteral研究
Guice对绑定泛型的类使用了一个小技巧。那就是通过TypeLiteral利用Java匿名内部类来获取绑定具体的Runtime时候的类型参数信息。
一段取类型参数的代码来自于:TypeLiteral.java line 98
/**
* Returns the type from super class's type parameter in {@link MoreTypes#canonicalize(Type)
* canonical form}.
*/
static Type getSuperclassTypeParameter(Class<?> subclass) {
Type superclass = subclass.getGenericSuperclass();
if (superclass instanceof Class) {
throw new RuntimeException("Missing type parameter.");
}
ParameterizedType parameterized = (ParameterizedType) superclass;
return canonicalize(parameterized.getActualTypeArguments()[0]);
}
代码很简单,主要目的就是从Class的genericSuperClass里面取类型参数信息。Java泛型的实现是runtime“擦除”式的,也就是在runtime的时候泛型的类已经是“固定”的。Class的信息并不会根据实例的信息而变化。以Map<K,V>为例子,编译好后的Map.class包含两个类型参数信息,一个是K,一个是V.
假设两个Map实例:
Map<Integer,String> a = new HashMap<Integer,String>();
Map<Key,Object> b = new HashMap<Key,Object>()
在Runtime的时候a,b都是同一个Map class的不同实例而已。类型参数在Runtime的时候已经不存在。通过a.class得到的Class里面不会包含任何具体如Integer,String的类型参数的信息。
要想获得一个泛型类的某个实例的具体参数类型信息,一个途径就是让某个实例的class被编译的时候就将具体的类型参数编译进去。 然后将这个class跟某个具体实例关联起来,以间接达到存储类型信息的效果。 Java的匿名内部类刚刚有这个效果。
例子:
假设有一个Test.java
public class Test<K, V> {
protected Test() {
}
}
这个被编译的具体的Test.class文件只会包办K,V两个类型参数,不具备实际意义。而下面这种写法就不一样
Test<String,Integer> test = new Test<String, Integer>() {};
代码在被编译的时候会编译一个Test的子类的匿名内部类。这个匿名内部类在编译的时候会将java.lang.String和Integer作为类型参数编译到class中去。这样通过探索test.class就可以取得他的类型参数是String和Integer。
匿名内部类的这样的实现,刚刚符合Guice此处的需求。于是就有了Guice中这样的用法
bind(new TypeLietral()<List<String>>{}).annotationWith(Named.names("Language")).to(new ArrayList<String>());
.
Java的匿名内部类对泛型的编译的方式被用在Guice中,不知道是无心插柳还是刻意为之? 呵呵
附带一个试验类:
import java.lang.reflect.ParameterizedType;
public class ExploreGenericType {
public static void main(String[] args) {
// exloreClass(ExploreGenericType.class);
Type type = exploreObject(new Test<String, Integer>() {
});
Type type2 = exploreObject(new TestChild<String, Integer>());
Type type3 = exploreObject(new TestStringInteger<String, Integer>());
if (type.equals(type2)) {
System.out.println("Their generic super class is same one.");
} else {
System.out.println("Their generic super class is not same one.");
}
// System.out.println(ArrayList.class.getGenericSuperclass());
}
private static Type exploreObject(Object object) {
System.out.println("Explore Object : " + object);
exloreClass(object.getClass());
return object.getClass().getGenericSuperclass();
}
private static void exloreClass(Class klass) {
System.out.println("Explore class : " + klass.getCanonicalName());
System.out.println((klass instanceof Type));
Type genericType = klass.getGenericSuperclass();
System.out.println(String.format("Class %s generic superclass is %s",
klass, genericType));
System.out.println(String.format("Generic type is a %s", genericType));
if (genericType instanceof Class) {
System.out.println("Generic is a Object.");
return;
}
ParameterizedType parameterized = (ParameterizedType) genericType;
System.out.println(String.format("%s parameterized Class is %s",
parameterized, parameterized.getActualTypeArguments()));
System.out.println(String.format("%s parameterized OwnerType is %s",
parameterized, parameterized.getOwnerType()));
System.out.println(String.format("%s parameterized RawType is %s",
parameterized, parameterized.getRawType()));
Type[] types = parameterized.getActualTypeArguments();
for (Type type : types) {
if (type instanceof TypeVariable) {
TypeVariable var = (TypeVariable) type;
System.out.println("Type Name is :" + var.getName());
System.out.println("Type GenericDeclaration is :"
+ var.getGenericDeclaration());
}
}
}
}
分享到:
相关推荐
guice 学习资料,快速掌握guice的编程技巧以及了解其机制。
Does this sound like you? • "My application is easy to unit-test!" • "I don't worry about Dependency Bloat!" • "My code is clean! It has high signal-to-noise!" • "My tests never mysteriously fail ...
Guice (pronounced "Juice") is the 100% Java icing on the cake of Java dependency injection. Unlike other popular DI frameworks such as Spring, Guice fully embraces modern Java language features and ...
guice.jar guice.jar guice.jar guice.jar guice.jar guice.jar guice.jar
该资源中包含如下jar包: reportng-1.1.4.jar(这个jar包是经过修改的,支持中文以及饼状图,贼好用) velocity-dep-1.4.jar java-client-2.1.0.jar guice-3.0.jar 使用方式请查看我的个人博客
Guice是Google开发的一个轻量级,基于Java5(主要运用泛型与注释特性)的依赖注入框架(IOC)。Guice非常小而且快。Guice是类型安全的,它能够对构造函数,属性,方法(包含任意个参数的任意方法,而不仅仅是setter...
Java guice3.0轻量级的依赖注入框架 组件guice 是轻量级的依赖注入框架,依赖注入是类将他们的依赖声明为参数,而不是直接创建依赖的一种设计模式。
java面试笔试题库java学习比较开发教程互联网公司面试资料大全合集: 100家大公司java笔试题汇总.doc 125条常见的java 面试笔试题大汇总.pdf 2011最新整理java经典代码.doc 25个经典的Spring面试问答.docx 8张图解...
标签:google、inject、guice、jar包、java、API文档、中英对照版; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码和结构保持不变,注释和说明精准...
Google Guice 这个高效的与Spring类似的依赖注入框架; MyBatis配置和使用; Google Guice与MyBatis集成,支持注解事务,简单的无法想象; Mybatis与mysql集成;实现发送邮件轮询; 源码是个web项目,里面有数据库的...
标签:google、inject、guice、jar包、java、中文文档; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码和结构保持不变,注释和说明精准翻译,请...
guice超轻量级依赖注入用了才知道是爽
google guice 3.0源码,官方下载,帮助你更好理解google guice实现的原理
标签:google、inject、extensions、guice、multibindings、中文文档、jar包、java; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码和结构保持不变...
标签:extensions、google、assistedinject、inject、guice、jar包、java、API文档、中英对照版; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码和...
Guice用户中文指南,Guice (读作"juice")是超轻量级的,下一代的,为Java 5及后续版本设计的依赖注入容器
Guice2中最轻的API扩展将极大地影响开发者代码的大小和维护。Guice2的开发者很好地平衡了可维护性和敏捷性。
用 Guice 写 Java Guice 1.0 用户指南 王咏刚 译 Guice (读作"juice")是超轻量级的,下一代的,为Java 5及后续版本设计的依赖注入容器。
依赖注入与JSR-330的参考实现——Guice.docx 关于Java框架Vert.x的几点思考.docx 关于堆和栈的那些事.docx 写好Java代码的30条经验总结.docx 华为java笔试面试题2014.doc 多态的理解.docx 大公司最喜欢问的Java集合...