在我的代码中,我想使用类似的类型参数:
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" )
可以)但左侧必须完全一样。
答案 0 :(得分:1)
一种方法可能是引入扩展类/接口的子类型并定义具体的类型参数,例如:像interface StringList extends List<String>
这样的东西。在build
方法中,您可以获得已传递的类的泛型类型。
电话会是这样的:
public static final ParameterDefinition<? extends List<String>> NAMES = ParameterDefinition.build( StringList.class, CURRENCY );
是的,这不是很优雅,但可能是一个开始。我会更多地考虑一下这个问题。 :)
答案 1 :(得分:0)
ParameterDefinition是一个通用类吗?换句话说,它被定义为
public class ParameterDefinition<T>
或
之外的其他内容public class ParameterDefintion
如果是,那么您可以返回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" );
答案 2 :(得分: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
包含的内容。
答案 3 :(得分:0)
从“注意”,我带你可以改变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:而不是ArgumentValidator
,请使用org.hamcrest.Matcher
。
这就是我所能想到的。如果您能更加具体地了解您的要求,那就太好了。