类型安全:来自对象的未经检查的强制转换
我尝试将一个对象强制转换为我的 Action 类,但结果出现警告:
Type safety: Unchecked cast from Object to Action<ClientInterface>
Action<ClientInterface> action = null;
try {
Object o = c.newInstance();
if (o instanceof Action<?>) {
action = (Action<ClientInterface>) o;
} else {
// TODO 2 Auto-generated catch block
throw new InstantiationException();
}
[...]
感谢您的帮助
I try to cast an object to my Action class, but it results in a warning:
Type safety: Unchecked cast from Object to Action<ClientInterface>
Action<ClientInterface> action = null;
try {
Object o = c.newInstance();
if (o instanceof Action<?>) {
action = (Action<ClientInterface>) o;
} else {
// TODO 2 Auto-generated catch block
throw new InstantiationException();
}
[...]
Thank you for any help
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
是的 - 这是类型擦除的自然结果。如果
o
实际上是Action
的一个实例,不会被强制转换捕获 - 只有当您尝试使用它时,您才会看到问题,通过在ClientInterface
中而不是字符串中。您可以使用:作为函数注释来消除警告
,但您无法轻松解决根本问题:(
Yes - this is a natural consequence of type erasure. If
o
is actually an instance ofAction<String>
that won't be caught by the cast - you'll only see the problem when you try to use it, passing in aClientInterface
instead of a string.You can get rid of the warning using:
as a function annotation, but you can't easily sort out the underlying problem :(
像往常一样,乔恩·斯基特是对的。
详细说明他的答案中不太容易的部分:
鉴于
您可以编写:
这消除了强制转换和警告,但代价是引入非泛型类型,因此您可以使用
.class
来获取类型足够准确的Class
对象。As usual, Jon Skeet is right.
To elaborate on the not-easily part of his answer:
Given
You can write:
This eliminates both the cast and the warning, at the price of introducing a non-generic type so you can use
.class
to get a sufficiently accurately typedClass
object.该警告意味着即使转换在运行时正常工作,编译器也无法保证类型安全。由于擦除,在运行时转换只是对 Action 的转换。底层泛型类可能不是预期的 ClientInterface 类型。在这种情况下,问题将在稍后(甚至可能更晚)以 ClassCastException 的形式出现。
在这种特定情况下,我建议通过以下编译器指令抑制此特定警告:
The warning means that the compiler can't guarantee type safety even if the casting works fine at runtime. Due to erasure, at runtime the casting is simply a casting to Action. It is possible that the underlying generic class is not of type ClientInterface as expected. In this case, the problem will appear later (maybe even much later), as a ClassCastException.
In this specific case I recommend suppressing this specific warning by the following compiler directive:
别担心。这是因为Java编译器无法知道对象的真实类型是什么。
Don't worry about. It is because the Java compiler has no way to know, what is the real type of the object.
这是一种沮丧。这是动态转换,编译器不知道引用指向的实际对象。
您收到此警告是因为转换
Action
的目标类型是参数化类型,并且编译器无法保证进行类型转换的对象属于同一类型。如果您不想抑制此警告并且不关心类型参数,则可以使用通配符将代码更改为:
这更安全,因为
instanceof
无法检查该警告o
是Action
的对象,它只是检查o
是否是Action
的对象,因为进一步泛型类型信息将在运行时擦除。This is a downcast. It's the dynamic cast where the compiler has no idea of the actual object the reference is pointing to.
You get this warning because the target type of the cast
Action<ClientInterface>
is a parameterized type and the compiler cannot guarantee that the object being type casted is of the same type.If you don't want to suppress this warning and don't care about the type parameter, you could change the code to this by using wildcards:
This is much safer because the
instanceof
can't check thato
is a object ofAction<ClientInterface>
, it just check ifo
is a object ofAction
since further generic type information will be erased at runtime.由于擦除(即参数化类型已被擦除),您丢失了类型信息,因此出现警告。除了清理周围的代码以便更频繁地使用泛型之外,您对此无能为力,因此您可以传递泛型类型信息并完全避免强制转换。
You've lost the type information because of erasure (i.e., the parameterised types have been erased), hence the warning. You can't do anything about it, other than clean up the surrounding code so that generics are used more frequently, so you can pass the generic type information and avoid casting at all.
现在您可以简单地执行
以下操作:如果 o 是实例 eof 操作,则对象将自动转换为操作
Now you can simply do
the object will be automatically casted to action if o is instanc eof action