首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >番石榴TypeToken和泛型类

番石榴TypeToken和泛型类
EN

Stack Overflow用户
提问于 2014-09-30 15:06:28
回答 2查看 5.3K关注 0票数 6

我在我的项目中使用了番石榴TypeToken类,但是我得到了一个意想不到的结果。

我有MyGenericClass<T>

代码语言:javascript
复制
public class MyGenericClass<T> implements MyInterface {

    private TypeToken<T> recordType;

    public MyGenericClass(String name) {
        this.recordType = new TypeToken<T>(getClass()) {};

        // ...
    }

    // ...

    @SuppressWarnings("unchecked")
    protected Class<T> getRecordType() {
        return (Class<T>) recordType.getRawType();
    }
}

因此,如果我通过new MyGenericClass<String>()实例化一个对象,然后调用getRecordType(),我希望得到java.lang.String,而不是得到java.lang.Object

但是,如果我扩展泛型类:

代码语言:javascript
复制
public class MyStringImpl extends  MyGenericClass<String> {
    // ...
}

并实例化这个新类:new MyStringImpl(),然后得到正确的结果。

为什么会发生这种情况?这是TypeToken的预期行为吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-09-30 15:27:13

要完成这项工作,实例化MyGenericClass时需要使用相同的匿名子类技巧。

代码语言:javascript
复制
new MyGenericClass<String>() {}

如果这样做,那么String将由getRecordType返回。在构造函数中解释了为什么这是必要的。

客户端创建一个空的匿名子类。这样做将类型参数嵌入到匿名类的类型层次结构中,这样我们就可以在运行时重新设置它,尽管删除了它。

票数 14
EN

Stack Overflow用户

发布于 2014-09-30 23:49:08

在伊恩的回答中添加一些无聊的细节:如果TypeToken按你预期的方式工作,那就太好了,但这是不可能的。当你宣布

代码语言:javascript
复制
public class MyGenericClass<T> implements MyInterface {...}

JVM看到的情况如下

代码语言:javascript
复制
public class MyGenericClass<Object> implements MyInterface {...}

因为擦除了。

但当你宣布

代码语言:javascript
复制
public class MyStringImpl extends MyGenericClass<String> {...}

然后,在MyStringImpl的定义中,对所使用的泛型进行记录,并通过Class#getGenericSuperclass()获得。这是TypeToken背后的神奇之处。

票数 15
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26124151

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档