0

在我的代码中,我想使用如下类型的参数:

public static final ParameterDefinition<List<String>> NAMES
    = ParameterDefinition.build( List.class, CURRENCY );

这让我以后可以写:

List<String> names = object.get( NAMES );

没有任何情况。

但它不编译(List不兼容List<String>)。

我可以使用以下代码进行编译:

@SuppressWarnings( { "unchecked", "rawtypes" } )
public static final ParameterDefinition<List<String>> NAMES
    = (ParameterDefinition) ParameterDefinition.build( List.class, "names" );

我怎样才能摆脱@SuppressWarnings?如何List<String>.class在 Java 6 中进行模拟?

注意:右侧的代码可能更复杂(即build(List.class, String.class, "names" )可以),但左侧的代码必须完全一样。

4

4 回答 4

1

一种方法可能是引入扩展类/接口并定义具体类型参数的子类型,例如interface StringList extends List<String>. 在build方法内部,您将能够获得已传递的类的泛型类型。

调用将如下所示:

public static final ParameterDefinition<? extends List<String>> NAMES = ParameterDefinition.build( StringList.class, CURRENCY  );

诚然,这不是很优雅,但可能是一个开始。我会多考虑一下。:)

于 2013-08-16T14:16:54.093 回答
0

从“注释”中,我认为您可以更改构建(?)的定义。您也没有指定是否ParameterDefinition实际需要知道类型。如果没有,这将解决问题:

public static <X> ParameterDefinition<X> build(String name);

如果您只需要参数,因为Java有时会愚蠢地猜测泛型类型,但方法中没有使用它,您也可以这样做

public static <X> ParameterDefinition<X> build(Class<? super X> type, String name);

如果ParameterDefinition使用 type 参数来确保值的类型,那么您应该知道没有可能的参数可以确保结果实际上是List<String>. 这可能就是您的问题没有简单解决方案的原因。

如果您不在乎,您可以执行以下操作:

public static <X> ParameterDefinition<X> build(Class<X> type, String name) { ... }

@SuppressWarnings({"unchecked", "rawtypes"})
public static <X> Class<List<X>> listOf(Class<X> itemType) {
    return (Class) List.class;
}

static ParameterDefinition<String> = build(String.class, "name");
static ParameterDefinition<List<String>> = build(listOf(String.class), "keywords");

这里的优点是SuppressWarnings它们在库代码中,API 用户不必处理它们。

如果列表的所有元素都是字符串实际上很重要,并且我假设您的实现应该是可扩展的,那么您将需要一种更复杂的方法:

public interface ArgumentValidator<X> {

    boolean accept(Object o)

}

public static <X> ArgumentValidator<X> instanceOf(Class<X> type) { ... }

public static <X> ArgumentValidator<List<X>> listOf(Class<X> itemType) { ... }

public static <X> ParameterDefinition<X> build(ArgumentValidator<X> validator, String name) { ... }

public static <X> ParameterDefinition<X> build(Class<X> type, String name) {
    return build(instanceOf(type), name);
}

static ParameterDefinition<String> = build(String.class, "name");
static ParameterDefinition<List<String>> = build(listOf(String.class), "keywords");

提示:代替ArgumentValidator, 使用org.hamcrest.Matcher.

这就是我能想到的。如果您可以更具体地了解您的要求,那就太好了。

于 2013-08-17T12:27:21.840 回答
0

ParameterDefinition 是泛型类吗?换句话说,它是否定义为

public class ParameterDefinition<T>

或以外的东西

public class ParameterDefintion

如果是这样,那么您可以返回 a ParameterDefintion<List<String>>,但如果不是,您需要决定在<T>该区域内放置什么值。

顺便说一句,在静态方法中添加 final 是没有效果的,而且是多余的。我会删除它。

在 ParameterDefinition 接受一个 Generics 参数后,你可以写

    public static final <X> ParameterDefinition<X> build(Class<X> clazz, String name) {
      ...
      return ...;
    }

你甚至不需要你的演员表

(ParameterDefinition) ParameterDefinition.build( List.class, "names" );
于 2013-08-16T13:59:52.560 回答
0

如果您想使用build(List.class, String.class, "names" ),那么您可以public class ParameterDefinition<T extends List<P>, P>用作类定义,这将允许像这样创建类ParameterDefinition<List<String>, String> test = new ParameterDefinition<List<String>, String>();

它不是很漂亮,但它应该可以工作,它允许您定义List包含的内容。

于 2013-08-16T14:28:08.733 回答