1

给定以下类型层次结构:

public class GenericBaseClass<T> { }

public class SpecializedClass<T, E extends Enum<E> & SomeInterface> extends GenericBaseClass<T> { }

public class SomeProvider {
    private static final List<SpecializedClass<Foo, ?>> VALUES =
        Arrays.asList(createValue());

    List<SpecializedClass<Foo, ?>> getValues() {        
        return VALUES;
    }

    private static SpecializedClass<Foo, Bar> createValue() {
        return new SpecializedClass<>();
    }
}

public class Foo {}
public enum Bar implements SomeInterface {}
public interface SomeInterface {}

SomeProvider应该公开可SpecializedClass用于具体类型的列表Foo。(为了简化这个例子,这里只给出了一个类型的具体内容Bar。)

根据https://rules.sonarsource.com/java/RSPEC-1452

不应在返回参数中使用通用通配符类型

此片段被声纳标记为关键代码异味。

到目前为止,我无法在这里摆脱通配符。将 getter 方法更改为

List<GenericBaseClass<Foo>> getValues() {        
    return VALUES;
}

将避免警告,但客户端会丢失该列表仅包含SpecializedClass.

基本上我在这里有两个问题:

  1. 在这种情况下,这真的是一种糟糕的代码气味吗?在这里使用这个 getter 方法的客户可能会遇到什么陷阱?

  2. 在返回类型中不使用通配符的情况下,getter 应该是什么样子?

非常感谢您的帮助。

4

1 回答 1

0

使用有什么问题

import java.util.Collections;
import java.util.List;

public class SomeProvider {

  private static final List<SpecializedClass<Foo, Bar>> VALUES =
      Collections.singletonList(createValue());

  List<SpecializedClass<Foo, Bar>> getValues () {
    return VALUES;
  }

  private static SpecializedClass<Foo, Bar> createValue () {
    return new SpecializedClass<>();
  }
}

?

编辑:

也可能但不确定您的静态代码分析是

import java.util.Arrays;
import java.util.List;

public class SomeProvider {

  private static final List<SpecializedClass<Foo, ? extends SomeInterface>> VALUES =
      Arrays.asList(createValue1(), createValue2());

  List<SpecializedClass<Foo, ? extends SomeInterface>> getValues () {
    return VALUES;
  }

  private static SpecializedClass<Foo, Bar1> createValue1 () {
    return new SpecializedClass<>();
  }

  private static SpecializedClass<Foo, Bar2> createValue2 () {
    return new SpecializedClass<>();
  }
}

这至少将您的返回类型绑定到SomeInterface.

于 2020-01-03T08:53:58.980 回答