gpt4 book ai didi

java - 静态成员中的泛型参数声明

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:31:57 25 4
gpt4 key购买 nike

为什么不允许定义这样的静态成员:

private static final <T extends Object> Map<Class<T>, BiFunction<T, T, Boolean>> SPECIFIC_HANDLERS = new HashMap<>();

相反,它只允许在未指定的情况下使用它:

private static final Map<Class<?>, BiFunction<?, ?, Boolean>> SPECIFIC_HANDLERS = new HashMap<>();

是否有解决方法,以便我可以定义 BiFunction 的两个参数必须是同一类型,并且 Map 的键必须是这些参数的类类型?

更新澄清(因为@Mena的建议不适合我):

我想要一个映射,用于通用 equals 助手的数组 equals 方法。通用助手正式接收两个对象。如果它们是数组,我必须将其传递给重载的 Arrays.equals() 方法之一。我想查找正确的方法(示例 1):

private static final Map<Class<?>, BiFunction<?, ?, Boolean>> ARRAY_EQUALS_HANDLER = new HashMap<>();

static
{
ARRAY_EQUALS_HANDLER.put( Object[].class, (l, r) -> Arrays.equals( (Object[]) l, (Object[]) r ));
ARRAY_EQUALS_HANDLER.put( boolean[].class, (l, r) -> Arrays.equals( (boolean[]) l, (boolean[]) r ));
....
}

然后像这样使用它:

boolean equal = ARRAY_EQUALS_HANDLER.get( anObj1.getClass()).apply(anObj1, anObj2);

构造(根据 Mena)甚至不编译:

private static <T extends Object> Map<Class<T>, BiFunction<T, T, Boolean>> getSpecificHandlers() 
{
Map<Class<T>, BiFunction<T, T, Boolean>> result = new HashMap<>();
result.put( Object[].class, (l, r) -> Arrays.equals( (Object[]) l, (Object[]) r ));
result.put( boolean[].class, (l, r) -> Arrays.equals( (boolean[]) l, (boolean[]) r ));
return result;
}

如果我在方法之外填充生成的 map :

 @SuppressWarnings( { "unchecked", "rawtypes" })
private static final Map<Class<?>, BiFunction<?, ?, Boolean>> ARRAY_EQUALS_HANDLER = (Map) getSpecificHandlers();

static
{
ARRAY_EQUALS_HANDLER.put( Object[].class, (l, r) -> Arrays.equals( (Object[]) l, (Object[]) r ));
...
}

然后整个类型安全就消失了,因为在将它分配给最终静态成员时我必须进行(未经检查的)类型转换。

上面的示例 1 有效,但在使用它时我必须转换接收到的 lambda :

private static <T extends Object> boolean equalsArray( T anArray, T anOtherArray) {
Object o = ARRAY_EQUALS_HANDLER.get( anArray.getClass());
@SuppressWarnings( "unchecked")
BiFunction<T, T, Boolean> func = (BiFunction<T, T, Boolean>) o;

Boolean result = func.apply( anArray, anOtherArray);
return result;
}

最佳答案

您正在使用泛型方法习惯用法(返回类型之前的类型参数声明),用于常量声明。

那个成语不会编译。

正如其他地方提到的,您不能在静态上下文中使用类泛型类型。

作为解决方法,您可以做的是声明一个静态方法而不是常量 - 类似于:

private static final <T extends WhateverBound> Map<Class<T>, 
BiFunction<T, T, Boolean>>
getSpecificHandlers(T t) {

// return new HashMap<Class<T>, BiFunction<T, T, Boolean>>();
// much easier on the eye - thanks Andy Turner
return new HashMap<>();
}

假设:

static class WhateverBound{}
static class Foo extends WhateverBound {}

然后您可以调用您的方法:

Map<Class<Foo>, BiFunction<Foo, Foo, Boolean>> map = 
getSpecificHandlers(new Foo());

当然请注意,此处的 final 关键字具有非常不同的含义,可能可以完全省略。

或者……

您可以将其保持为常量并在所有类型参数化中重复通配符/边界模式。

例如:

private static final Map<Class<? extends WhateverBound>, 
BiFunction<? extends WhateverBound, ? extends WhateverBound, Boolean>>
SPECIFIC_HANDLERS = new HashMap<>();

static {
SPECIFIC_HANDLERS.put(Foo.class, (f, ff) -> true);
}

关于java - 静态成员中的泛型参数声明,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35774313/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com