在我的代码中,我想使用类型化的参数,比如:
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
?如何在Java 6中模拟List<String>.class
?
注意:右手边的代码可能更复杂(即build(List.class, String.class, "names" )
可以),但左手边必须完全原样。
一种方法可能是引入扩展类/接口并定义具体类型参数的子类型,例如interface StringList extends List<String>
。在build
方法中,您将能够获得已传递的类的泛型类型。
通话内容如下:
public static final ParameterDefinition<? extends List<String>> NAMES = ParameterDefinition.build( StringList.class, CURRENCY );
的确,这不是很优雅,但可能是一个开始。我会多考虑一下的。:)
根据"注释",我认为您可以更改build(?)的定义。您也没有指定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用户不必处理它们。
如果列表中的所有元素都是String这一点非常重要,并且我认为您的实现应该是可扩展的,那么您将需要一种更复杂的方法:
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");
Protip:使用org.hamcrest.Matcher
代替ArgumentValidator
。
这就是我所能想到的。如果你能对你的要求更具体一点,那就太好了。
public class ParameterDefinition<T>
或者以外的东西
public class ParameterDefintion
如果是,则可以返回ParameterDefintion<List<String>>
,但如果不是,则需要决定在<T>
区域中放置什么值。
顺便说一句,在静态方法中添加final没有任何效果,而且是多余的。我会把它取下来。
ParameterDefinition获取泛型参数后,您可以编写
public static final <X> ParameterDefinition<X> build(Class<X> clazz, String name) {
...
return ...;
}
你甚至不需要的演员阵容
(ParameterDefinition) ParameterDefinition.build( List.class, "names" );
如果您想使用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
包含的内容。