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的编程技巧以及了解其机制。
### Java on Guice:深入理解依赖注入 #### 核心概念与价值 “Java on Guice”这篇文档探讨了依赖注入(Dependency Injection, DI)在Java应用中的实践方式及其带来的诸多好处。它由Google的Bob Lee和Kevin ...
Java Guice 3.0是一款轻量级的依赖注入(Dependency Injection, DI)框架,它致力于简化Java应用程序的构建过程,让组件之间的依赖关系更加清晰和易于管理。依赖注入是一种设计模式,它允许代码在运行时自动管理和...
5. **注解处理(Annotation Processing)**:Guice使用Java的注解处理工具(APT)在编译时生成元数据,从而在运行时提高效率。这包括生成代理类和绑定类。 6. **AOP(面向切面编程)支持**:虽然Guice不是专门的AOP...
例如,`AromaRI`可能是一个使用Guice实现的后台服务,通过Guice管理其内部的各种组件和服务之间的依赖关系。 在阅读《初试Guice》这篇博客文章时,你可能会学习到如何设置Guice模块,如何声明和注入依赖,以及如何...
### Java Guice 依赖注入教程 #### 概述 本文档详细介绍如何利用 Google 开源的依赖注入框架 Guice 进行 Java 开发。通过本文档的学习,开发者将能够更好地理解 Guice 的工作原理及其在实际项目中的应用。文档涵盖...
Java依赖注入框架Guice2是Google开发的一款轻量级的依赖注入库,它极大地简化了Java应用程序中的对象创建和管理。Guice2以其简洁的API和强大的功能在开发者社区中赢得了广泛的认可。依赖注入(Dependency Injection...
2. **易用性**:Guice的学习曲线平缓,开发者可以快速上手。 3. **可扩展性**:支持自定义绑定和拦截器,方便集成其他框架或库。 4. **灵活性**:Guice允许在运行时动态地配置依赖关系。 5. **强大的社区支持**:...
2. **注解驱动**:Guice使用Java的注解来标记接口和实现,如`@Inject`用于标记构造函数、字段或方法,表示需要依赖注入。`@Singleton`表示该对象为单例,`@Named`用于指定特定的依赖实现。 3. **模块(Modules)**...
**基于Guice的简单项目** 在Java开发中,依赖注入(Dependency Injection,简称DI)是一种设计...通过学习和实践这个项目,开发者可以更好地掌握Guice的工作原理和使用技巧,为未来的Java项目带来更高效的代码结构。
在提供的文件中,我们可以看到几个关键的类,如`Test.java`、`MyModule.java`、`Client.java`、`MyService01.java`、`Service01Impl.java`、`MyServiceImpl.java`和`MyService.java`,它们展示了Guice如何工作。...
1. **定义模块**:首先定义一个 Guice 模块来绑定接口与其实现类。 ```java public class ServiceModule extends AbstractModule { @Override protected void configure() { bind(Service.class).to...
Guice,全称为Google Guice,是Google推出的一款轻量级的依赖注入(Dependency Injection,简称DI)框架,专门用于简化Java应用中的对象组装和管理。依赖注入是一种设计模式,它可以帮助开发者降低代码间的耦合,...
### Java on Guice – Dependency Injection the Java Way #### 关键知识点概述 - **依赖注入(Dependency Injection, DI)**:一种软件设计模式,用于管理组件之间的依赖关系。 - **Guice**:由Google开发的一个...
Google Guice作为一款100%纯Java实现的依赖注入框架,以其简单性、高性能和易于使用的特性而受到广泛好评。本书《Google Guice: Agile Lightweight Dependency Injection Framework》旨在深入探讨Guice的核心概念和...
**Guice 概述** ...通过中文文档和示例,开发者可以更轻松地学习和运用 Guice,以实现更优雅、可扩展的代码结构。在实践中,结合文档和示例,不断实践和理解 Guice 的各种特性,将有助于提升开发效率和软件质量。
Apache Shiro 和 Google Guice 的整合是为了解决在Java应用程序中实现权限管理的问题。Shiro 是一个强大且易用的 Java 安全框架,提供了认证、授权、加密和会话管理功能,可以非常轻松地开发出足够安全的应用。而 ...
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 使用方式请查看我的个人博客