如何摆脱这个泛型警告?

发布于 2024-09-09 05:27:57 字数 465 浏览 5 评论 0原文

我试图模拟一个通用接口,每当我模拟它时,我都会收到此警告:

GenericInterface 类型的表达式需要未经检查的转换以符合 GenericInterface

我的界面是

interface GenericInterface<T>{
    public T get();
}

,我的测试是

@Test
public void testGenericMethod(){
    GenericInterface<String> mockedInterface = EasyMock.createMock(GenericInterface.class);
}

我在测试用例的第一行收到警告。

如何删除此一般警告?

I am trying to mock a generic interface, and whenever I mock it, I gets this warning:

The expression of type GenericInterface needs unchecked conversion to conform to GenericInterface<String>

My interface is

interface GenericInterface<T>{
    public T get();
}

and my test is

@Test
public void testGenericMethod(){
    GenericInterface<String> mockedInterface = EasyMock.createMock(GenericInterface.class);
}

I get warning at the first line in test case.

How do I remove this generic warning?

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

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

发布评论

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

评论(4

樱桃奶球 2024-09-16 05:27:57

消除警告的正确步骤是:

  • 首先,证明未经检查的强制转换是安全的,并记录原因
  • 然后才执行未经检查的强制转换,并注释< code>@SuppressWarnings("unchecked") 在变量声明上(而不是在整个方法上)

所以像这样:

// this cast is correct because...
@SuppressWarnings("unchecked")
GenericInterface<String> mockedInterface =
    (GenericInterface<String>) EasyMock.createMock(GenericInterface.class);

指南

以下摘录自有效的 Java 第二版:第 24 项:消除未经检查的警告< /em>:

  • 尽可能消除所有未经检查的警告。
  • 如果您无法消除警告,并且可以证明引发警告的代码是类型安全的,那么(并且只有这样)才能使用 @SuppressWarning("unchecked") 抑制警告注释。
  • 始终在尽可能小的范围内使用 SuppressWarning 注释。
  • 每次使用 @SuppressWarning("unchecked") 注释时,请添加一条注释,说明为什么这样做是安全的。

相关问题


重构强制转换

在大多数情况下也可以在通用 createMock 中执行未经检查的强制转换。它看起来像这样:

static <E> Set<E> newSet(Class<? extends Set> klazz) {
    try {
        // cast is safe because newly instantiated set is empty
        @SuppressWarnings("unchecked")
        Set<E> set = (Set<E>) klazz.newInstance();
        return set;
    } catch (InstantiationException e) {
        throw new IllegalArgumentException(e);
    } catch (IllegalAccessException e) {
        throw new IllegalArgumentException(e);          
    }
}

然后在其他地方你可以简单地做:

// compiles fine with no unchecked cast warnings!
Set<String> names = newSet(HashSet.class);
Set<Integer> nums = newSet(TreeSet.class);

另请参阅

The correct steps to get rid of the warning is:

  • First and foremost, prove that the unchecked cast is safe, and document why
  • Only then perform the unchecked cast, and annotate @SuppressWarnings("unchecked") on the variable declaration (not on the whole method)

So something like this:

// this cast is correct because...
@SuppressWarnings("unchecked")
GenericInterface<String> mockedInterface =
    (GenericInterface<String>) EasyMock.createMock(GenericInterface.class);

Guidelines

The following is excerpt from Effective Java 2nd Edition: Item 24: Eliminate unchecked warnings:

  • Eliminate every unchecked warning that you can.
  • If you can't eliminate a warning, and you can prove that the code that provoked the warning is typesafe, then (and only then) suppress the warning with @SuppressWarning("unchecked") annotation.
  • Always use the SuppressWarning annotation on the smallest scope possible.
  • Every time you use an @SuppressWarning("unchecked") annotation, add a comment saying why it's safe to do so.

Related questions


Refactoring the cast

It is also possible in most cases to perform the unchecked cast inside a generified createMock. It looks something like this:

static <E> Set<E> newSet(Class<? extends Set> klazz) {
    try {
        // cast is safe because newly instantiated set is empty
        @SuppressWarnings("unchecked")
        Set<E> set = (Set<E>) klazz.newInstance();
        return set;
    } catch (InstantiationException e) {
        throw new IllegalArgumentException(e);
    } catch (IllegalAccessException e) {
        throw new IllegalArgumentException(e);          
    }
}

Then elsewhere you can simply do:

// compiles fine with no unchecked cast warnings!
Set<String> names = newSet(HashSet.class);
Set<Integer> nums = newSet(TreeSet.class);

See also

巷雨优美回忆 2024-09-16 05:27:57

这里的问题是 EasyMock.createMock() 将返回 GenericInterface 类型的对象,而不是 GenericInterface 类型。您可以使用 @SupressWarnings 注释来忽略警告,或者您可以尝试显式转换为 GenericInterface(不过我认为这只是给出了不同的警告。)

The problem here is that EasyMock.createMock() is going to return an object of type GenericInterface and not GenericInterface<String>. You could use the @SupressWarnings annotation to ignore the warning, or you could try and explicit cast to GenericInterface<String> (I think this just gives a different warning though.)

梦里的微风 2024-09-16 05:27:57

似乎讨论了相同的警告......

我想@SuppressWarnings可能是这种情况下幸福的关键

seem to discuss the same warning...

i guess @SuppressWarnings might be the key to happiness in that case

梨涡少年 2024-09-16 05:27:57

如果您真的坚持避免编译器警告,您可以在测试中声明一个接口,只是为了避免它。

 interface MockGenericInterface extends GenericInterface<String> {}

然后你可以这样做:

 GenericInterface<String> mockedInterface = EasyMock.createMock(MockGenericInterface.class);

If you are really stuck up on avoiding the compiler warning, you can declare an interface in your test just for the purpose of avoiding it.

 interface MockGenericInterface extends GenericInterface<String> {}

Then you can do:

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