Java 类型安全:来自 Object 的未经检查的强制转换
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2592642/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Type safety: Unchecked cast from Object
提问by Matthew
I try to cast an object to my Action class, but it results in a warning:
我尝试将一个对象强制转换为我的 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();
}
[...]
Thank you for any help
感谢您的任何帮助
采纳答案by Jon Skeet
Yes - this is a natural consequence of type erasure. If o
is actually an instance of Action<String>
that won't be caught by the cast - you'll only see the problem when you try to use it, passing in a ClientInterface
instead of a string.
是的 - 这是类型擦除的自然结果。Ifo
实际上是一个实例,Action<String>
它不会被演员表捕获 - 只有在尝试使用它时才会看到问题,传入一个ClientInterface
而不是字符串。
You can get rid of the warning using:
您可以使用以下方法消除警告:
@SuppressWarnings("unchecked")
as a function annotation, but you can't easily sort out the underlying problem :(
作为一个函数注解,但你不能轻易理清潜在的问题:(
回答by Petar Minchev
Don't worry about. It is because the Java compiler has no way to know, what is the real type of the object.
别担心。这是因为Java编译器无法知道,对象的真正类型是什么。
回答by Chris Dennett
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.
由于擦除(即参数化类型已被擦除),您丢失了类型信息,因此发出警告。除了清理周围的代码以便更频繁地使用泛型之外,您无能为力,因此您可以传递泛型类型信息并完全避免强制转换。
回答by Eyal Schneider
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.
该警告意味着即使转换在运行时正常工作,编译器也无法保证类型安全。由于擦除,在运行时转换只是对 Action 的转换。底层泛型类可能不是预期的 ClientInterface 类型。在这种情况下,问题将在稍后(甚至可能更晚)出现,作为 ClassCastException。
In this specific case I recommend suppressing this specific warning by the following compiler directive:
在这种特定情况下,我建议通过以下编译器指令取消此特定警告:
@SuppressWarnings("unchecked")
回答by meriton
As usual, Jon Skeet is right.
像往常一样,乔恩斯基特是对的。
To elaborate on the not-easily part of his answer:
详细说明他的答案中不容易的部分:
Given
给定的
class ClientAction implements Action<ClientInterface> {}
You can write:
你可以写:
Class<? extends Action<ClientInterface>> c = ClientAction.class;
Action<ClientInterface> action = c.newInstance();
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 typed Class
object.
这消除了强制转换和警告,代价是引入了非泛型类型,因此您可以使用它.class
来获得足够准确的类型Class
对象。
回答by upupming
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 typeand the compiler cannot guarantee that the object being type casted is of the same type.
您收到此警告是因为强制转换的目标类型Action<ClientInterface>
是参数化类型,并且编译器无法保证被强制转换的对象类型相同。
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:
如果您不想取消此警告并且不关心类型参数,则可以使用通配符将代码更改为此:
Action<?> action = null;
try {
Object o = c.newInstance();
if (o instanceof Action<?>) {
action = (Action<?>) o;
} else {
// TODO 2 Auto-generated catch block
throw new InstantiationException();
}
[...]
This is much safer because the instanceof
can't check that o
is a object of Action<ClientInterface>
, it just check if o
is a object of Action
since further generic type information will be erasedat runtime.
这更安全,因为instanceof
无法检查它o
是否是 of 的对象Action<ClientInterface>
,它只是检查是否o
是 of 的对象,Action
因为在运行时将删除进一步的泛型类型信息。