类型安全:来自对象的未经检查的强制转换

发布于 2024-08-27 19:42:27 字数 415 浏览 13 评论 0原文

我尝试将一个对象强制转换为我的 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

半岛未凉 2024-09-03 19:42:27

是的 - 这是类型擦除的自然结果。如果 o 实际上是 Action 的一个实例,不会被强制转换捕获 - 只有当您尝试使用它时,您才会看到问题,通过在 ClientInterface 中而不是字符串中。

您可以使用:作为函数注释来消除警告

@SuppressWarnings("unchecked")

,但您无法轻松解决根本问题:(

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.

You can get rid of the warning using:

@SuppressWarnings("unchecked")

as a function annotation, but you can't easily sort out the underlying problem :(

一萌ing 2024-09-03 19:42:27

像往常一样,乔恩·斯基特是对的。

详细说明他的答案中不太容易的部分:

鉴于

class ClientAction implements Action<ClientInterface> {}

您可以编写:

Class<? extends Action<ClientInterface>> c = ClientAction.class;
Action<ClientInterface> action = c.newInstance();

这消除了强制转换和警告,但代价是引入非泛型类型,因此您可以使用 .class 来获取类型足够准确的 Class 对象。

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.

注定孤独终老 2024-09-03 19:42:27

该警告意味着即使转换在运行时正常工作,编译器也无法保证类型安全。由于擦除,在运行时转换只是对 Action 的转换。底层泛型类可能不是预期的 ClientInterface 类型。在这种情况下,问题将在稍后(甚至可能更晚)以 ClassCastException 的形式出现。

在这种特定情况下,我建议通过以下编译器指令抑制此特定警告:

@SuppressWarnings("unchecked")

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:

@SuppressWarnings("unchecked")
花桑 2024-09-03 19:42:27

别担心。这是因为Java编译器无法知道对象的真实类型是什么。

Don't worry about. It is because the Java compiler has no way to know, what is the real type of the object.

半步萧音过轻尘 2024-09-03 19:42:27

这是一种沮丧。这是动态转换,编译器不知道引用指向的实际对象。

您收到此警告是因为转换 Action 的目标类型是参数化类型,并且编译器无法保证进行类型转换的对象属于同一类型。

如果您不想抑制此警告并且不关心类型参数,则可以使用通配符将代码更改为:

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();
 }
 [...]

这更安全,因为 instanceof 无法检查该警告oAction 的对象,它只是检查 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:

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 erased at runtime.

夜雨飘雪 2024-09-03 19:42:27

由于擦除(即参数化类型已被擦除),您丢失了类型信息,因此出现警告。除了清理周围的代码以便更频繁地使用泛型之外,您对此无能为力,因此您可以传递泛型类型信息并完全避免强制转换。

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.

挽清梦 2024-09-03 19:42:27

现在您可以简单地执行

  if (o instanceof Action<ClientInterface> action) {
   //now you can use action
   }

以下操作:如果 o 是实例 eof 操作,则对象将自动转换为操作

Now you can simply do

  if (o instanceof Action<ClientInterface> action) {
   //now you can use action
   }

the object will be automatically casted to action if o is instanc eof action

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文