Java泛型-这种未检查的强制转换安全吗?

Java泛型-这种未检查的强制转换安全吗?,java,generics,casting,warnings,Java,Generics,Casting,Warnings,我还有一个问题。我90%确信它是安全的,但我想确保(我向另一个正在查看代码的开发人员证明使用@superswarnings是合理的) 我们的框架建立了以下模式: abstract class Writer<T> { Class<T> valueType; Writer(Class<T> valueType) { this.valueType = valueType; } } class Cat { } class C

我还有一个问题。我90%确信它是安全的,但我想确保(我向另一个正在查看代码的开发人员证明使用
@superswarnings
是合理的)

我们的框架建立了以下模式:

abstract class Writer<T> {
    Class<T> valueType;

    Writer(Class<T> valueType) {
        this.valueType = valueType;
    }
}
class Cat { }

class CatWriter extends Writer<Cat> {
    CatWriter() {
        super(Cat.class);
    }
}
我的writer类如下所示:

abstract class Bird<C extends Color> {}
class Parrot extends Bird<Green>{}
class Ostrich extends Bird<Brown>{}

class BirdWriter<C extends Color> extends Writer<Bird<C>> {
    BirdWriter(Bird<C> bird) {
        super((Class<Bird<C>>)bird.getClass());
    }
}
同样,我也有同样的警告,但这似乎更安全


这更好吗?它安全吗?
Class<this> getClass();
Class getClass();

可能是因为这是唯一一个使用它的例子。

你不是完全正确的。正确、安全但仍未检查的强制转换是到
Class它肯定是不正确的,原因由ILMTitan列出。但我会给你一个理由,为什么它可能也不是很安全。假设您有一个方法
verifyType()
,该方法确保为写入而传入的任何内容都是正确的类型:

public void write(T t) {
   if (!verifyType(t)) explode();
   //...do write
}

public boolean verifyType(T t) {
   return valueType.isInstance(t);
}
这种方法你永远不会失败,对吧?毕竟,您只是在确保
t
t
(因为您有一个
Class
),我们已经知道它是
t
,因为
write()
只接受
t
?对吧?错了您实际上并不是在检查
t
是否为
t
,而是检查
t
的任意子类型

检查如果您声明了一个
编写器
,并用一个
鹦鹉
对其进行实例化,则执行此调用是合法的:

Writer<Bird<Green>> writer;
writer.write(new SomeOtherGreenBird());
Writer;
写(新的一些其他的绿鸟());

你也不会指望它会失败。但是,您的值类型仅适用于
Parrot
,因此类型检查将失败。这完全取决于你在写作课上做了什么,但要预先警告:你在这里踩的是危险的水。声明一个
类比我强。
不再是
,正如
列表
列表
。它可能是类型安全的,但这需要我们更多地了解
Writer
如何使用它。如果你的
作者
接受了
课程,非常感谢-这很有意义,也暴露了我所做的事情的古怪之处。我更好地理解了模式,修改了用例并更新了问题-你能回答第二个问题吗?再次感谢。就在我发布之后,我再次阅读了你的问题,并实现了你说会爆炸的代码。现在仍然如此。但是,我没有任何这样的检查,write是纯多态的,所以我应该很好,但至少我知道如何在类注释中解释这一点。谢谢
public void write(T t) {
   if (!verifyType(t)) explode();
   //...do write
}

public boolean verifyType(T t) {
   return valueType.isInstance(t);
}
Writer<Bird<Green>> writer;
writer.write(new SomeOtherGreenBird());