Class的Java泛型问题

时间:2009-11-27 18:18:38

标签: java generics

无法弄清楚这个泛型问题。我有这些接口:

public interface LoadableObject
{
}
public interface LoadableObjectFactory<T>
{
}

现在我想这样做:

public class ObjectReference<T extends LoadableObject>
{
    Class<? extends LoadableObjectFactory<T>> _cls;

    public ObjectReference(LoadableObjectFactory<T> obj)
    {
        _cls = obj.getClass();
    }
}

但是我收到了一个错误:

incompatible types
found   : java.lang.Class<capture#885 of ? extends test.LoadableObjectFactory>
required: java.lang.Class<? extends test.LoadableObjectFactory<T>>
  _cls = obj.getClass();
                     ^

如果我在LoadableObjectFactory的定义中移除了_cls的类型参数,我可以编译,但是它是一个不完整的类型...是否有我遗漏的东西或者它只是不可能?

4 个答案:

答案 0 :(得分:4)

运行时的getClass()提供了Class&lt;?&gt;。由于类型擦除,关于通用参数的信息不可用。你必须做一个演员

    @SuppressWarnings("unchecked")
public ObjectReference(LoadableObjectFactory<T> obj)
{
    _cls = (Class<? extends LoadableObjectFactory<T>>) obj.getClass();
}

让它运作

答案 1 :(得分:4)

这是info about type erasure,直接来自马的嘴,可以这么说。

这个东西伤到了我的思考,所以我不会试图解释它。可以说有一些操作你期望工作,但是因为Java“忘记”模块之间类型的通用细节,所以它们没有。

你可能无法使用这些信息,但是在Java中构建泛型的人已经去了并设计了一种全新的类似Java的语言:它被称为Scala。 Scala可以更好地处理类型和泛型;你可以说它在这方面做的一切都是正确的。它也可以在JVM中运行,您可以在Scala和Java类之间调用。

我个人对Scala的看法是,它是一个巧妙管理复杂类型的系统,偶然也可以用作编程语言。 :)

答案 2 :(得分:1)

我不会指责'类型擦除'。静态查看代码,它显然是安全的,它应该在更好的世界中传递编译器。

Java Generics太复杂了,不值得花时间弄清楚每一个细节。如果你知道你比编译器更清楚,那就做任何事情来绕过它。

答案 3 :(得分:0)

我原以为LoadableObjectFactory看起来像这样:

public interface LoadableObjectFactory<T extends LoadableObject>

说过--Object.getClass()返回一个无类型的类,所以你必须强制转换它。要修复它,必须将java.lang.Object的签名更改为

class Object<T extends Object<T>> {
    native Class<T> getClass();
}

但是对java.lang.Object的改动将涉及到几乎无处不在的大手术。