有没有办法避免此代码中的@SuppressWarnings?

发布于 2024-09-19 06:10:17 字数 533 浏览 4 评论 0原文

有没有办法避免使用下面的 @SuppressWarnings 并保持相同的功能而不出现警告“类型安全:从 AbstractDO[] 到 E[] 的未经检查的转换”:

public MyClass {
  ...
  private Map<Class<? extends AbstractDO>, AbstractDO[]> map;
  ...
  private void saveConcreteDOs(AbstractDO[] theEntities) {        
    entityMap.put(theEntities[0].getClass(), theEntities);
  }

  @SuppressWarnings("unchecked")
  protected <E extends AbstractDO> E[] getConcreteDOs(Class<E> theType) {
    return (E[]) map.get(theType);
  }
  ...
}

也许加强地图申报?

Is there a way to avoid using @SuppressWarnings below and to keep the same functionality without the warning 'Type safety: Unchecked cast from AbstractDO[] to E[]':

public MyClass {
  ...
  private Map<Class<? extends AbstractDO>, AbstractDO[]> map;
  ...
  private void saveConcreteDOs(AbstractDO[] theEntities) {        
    entityMap.put(theEntities[0].getClass(), theEntities);
  }

  @SuppressWarnings("unchecked")
  protected <E extends AbstractDO> E[] getConcreteDOs(Class<E> theType) {
    return (E[]) map.get(theType);
  }
  ...
}

Maybe enhance map declaration?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

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

发布评论

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

评论(3

眉目亦如画i 2024-09-26 06:10:17

您有一个选择:要么抑制您知道总会成功的强制转换的警告,要么避免警告并使用 try/catch 块验证强制转换是否成功。

只有这两个选择。

也许有一种方法可以增强地图声明?

就你的情况而言,我想说你有几个选择。

我认为最好的选择是在您的 getConcreteDOs 方法中添加一个 throws ClassCastException 子句,并让调用者处理因该方法的无效使用而导致的无效转换 -假设他们可以让它围绕您的 extends AbstractDO 子句进行编译。这会产生不幸的副作用,即强制使用者将调用包装在 try/catch 块中,或者声明自己的 throws 子句以强制 try/catch 块位于堆栈的更高位置。

你可以用一个空的 catch 块来吞掉异常;坦率地说,我更喜欢@SuppressWarning。

或者,您可以完全放弃该方法,只处理抽象实体,从而有效地使存储库的使用者处理强制转换。

底线:每当您尝试构建通用存储库时,您都会遇到这些问题。使用每个实体类型的具体存储库模式可能会更好。

You have a choice: either suppress the warning for a cast you know will always succeed, or avoid the warning and verify that the cast succeeded with a try/catch block.

There are only those two choices.

maybe there is a way to enhance map declaration?

In your case, I'd say you have a few options.

I think your best bet is to add a throws ClassCastException clause to your getConcreteDOs method and let the caller deal with an invalid cast brought on by an invalid use of the method -- assuming they could get it to compile around your extends AbstractDO clause. This has the unfortunate side effect of forcing the consumer to wrap the call in a try/catch block or declare their own throws clause to force a try/catch block higher up the stack.

You could just swallow the exception with an empty catch block; frankly I'd prefer the @SuppressWarning over that.

Or you could drop the method entirely and only deal in abstract entities, effectively making the consumer of your repository deal with the cast.

Bottom line: you're going to have these issues whenever you try to build generic repositories. You might be better off with a concrete-repository-per-entity-type pattern.

尛丟丟 2024-09-26 06:10:17

您可以通过使类通用来避免未经检查的强制转换,例如

public class MyClass<E extends AbstractDO> {

    private Map<Class<? extends AbstractDO>, E[]> map;

    public void saveConcreteDOs(E[] theEntities) {        
      map.put(theEntities[0].getClass(), theEntities);
    }

    public E[] getConcreteDOs(Class<E> theType) {
      return map.get(theType);
    }
}

You can avoid the unchecked cast by making your class generic, e.g.

public class MyClass<E extends AbstractDO> {

    private Map<Class<? extends AbstractDO>, E[]> map;

    public void saveConcreteDOs(E[] theEntities) {        
      map.put(theEntities[0].getClass(), theEntities);
    }

    public E[] getConcreteDOs(Class<E> theType) {
      return map.get(theType);
    }
}
只为一人 2024-09-26 06:10:17

首先,您的代码不是类型安全的。它可以在运行时抛出类转换异常。你应该

  private void saveConcreteDOs(AbstractDO[] theEntities) {        
    entityMap.put(theEntities.getClass().getComponentType(), theEntities);
  }

在运行时只有同构数组,并且 element[0] 与数组组件类型具有相同的类型。然而,仅通过考试这门课是无法知道这一点的。

通过这个更正的代码,超级智能编译器可以证明 getConcreteDOs() 是类型安全的。然而 javac 并不那么聪明。语言规范要求发出警告。

一般来说,Java 中没有办法表达键和值之间更复杂的关系。值是一个数组,其组件类型是键,这一不变量仅保留在您的头脑中。

现在,看看这个非数组版本:

private Map<Class<? extends AbstractDO>, AbstractDO> map;

protected <E extends AbstractDO> E getConcreteDOs(Class<E> theType) 
{
  AbstractDO obj = map.get(theType);
  return theType.cast(obj);
}

这没有警告,但它是一种作弊。 Class.cast() 为我们隐藏了警告,仅此而已。

它对数组版本没有帮助,Class 中没有 T[] castArray(Object[])。你可以自己制定一种方法,有效地将警告隐藏在其中。

或者你可以这样做,但它真的没有必要俗气。如果您知道自己在做什么并且仔细检查了程序以确保类型安全,请不要害怕未经检查的强制转换警告。

protected <E extends AbstractDO> E[] getConcreteDOs(Class<E[]> arrayType) 
{
  AbstractDO[] array = map.get(arrayType.getComponentType());
  return arrayType.cast(array);
}
...
X[] array = getConcreteDOs(X[].class);

First, your code is not type safe. It can throw class cast exception at runtime. You should have

  private void saveConcreteDOs(AbstractDO[] theEntities) {        
    entityMap.put(theEntities.getClass().getComponentType(), theEntities);
  }

You may have only homogeneous arrays at runtime, and element[0] has the same type as the array component type. However, there's no way to know that by examing this class alone.

With this corrected code, a super smart compiler can prove that getConcreteDOs() is type safe. However javac is not that smart. It's required by language spec to throw a warning.

Generally, there is no way to express more sophisticated relations between keys and values in Java. The invariant, that a value is an array whose component type is the key, is only maintained in your head.

Now, look at this non-array version:

private Map<Class<? extends AbstractDO>, AbstractDO> map;

protected <E extends AbstractDO> E getConcreteDOs(Class<E> theType) 
{
  AbstractDO obj = map.get(theType);
  return theType.cast(obj);
}

This has no warning, but it's kind of cheating. Class.cast() hides the warning for us, that's all.

It doesn't help the array version, there is no T[] castArray(Object[]) in Class<T>. You can make one method yourself, effectively hide the warning in it.

Or you can do this, but it's really unnecessarily tacky. Don't be afraid of unchecked cast warning if you know what you are doing and you examined carefully your program to ensure type safety.

protected <E extends AbstractDO> E[] getConcreteDOs(Class<E[]> arrayType) 
{
  AbstractDO[] array = map.get(arrayType.getComponentType());
  return arrayType.cast(array);
}
...
X[] array = getConcreteDOs(X[].class);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文