7

考虑在Effective Java generics 一章UnaryFunction中定义的接口。

public interface UnaryFunction<T> {
T apply(T arg);
}

以及以下用于返回的代码UnaryFunction

// Generic singleton factory pattern
private static UnaryFunction<Object> IDENTITY_FUNCTION = new UnaryFunction<Object>() {
  public Object apply(Object arg) { return arg; }
};

// IDENTITY_FUNCTION is stateless and its type parameter is
// unbounded so it's safe to share one instance across all types.
@SuppressWarnings("unchecked")
public static <T> UnaryFunction<T> identityFunction() {
  return (UnaryFunction<T>) IDENTITY_FUNCTION;
}

为什么演员表IDENTITY_FUNCTION(UnaryFunction<T>)安全的?

这本书对我提出的问题进行了说明,但我无法遵循这里的逻辑。我们在哪里调用apply执行身份操作的函数?我很困惑,因为它是返回传递给它的相同对象而不修改任何东西的函数。

IDENTITY_FUNCTION 的强制转换(UnaryFunction<T>)生成一个未经检查的强制转换警告,因为UnaryFunction<Object>它不是一个 UnaryFunction<T>for each T。但是标识函数很特殊:它返回未修改的参数,因此我们知道将其用作类型安全UnaryFunction<T>的值是T. 因此,我们可以放心地抑制此强制转换生成的未经检查的强制转换警告。完成此操作后,代码编译时不会出现错误或警告。

4

3 回答 3

3

带类型擦除

T apply(T arg);

实际上是

Object apply(Object arg);

现在是身份

Abc x = ...;
Abc y = IDENTITY.apply(x);

可以假设它总是正确的(相当于y = x;)。

(非常务实。)

于 2013-02-25T16:53:03.827 回答
3

强制转换是安全的,因为标识函数首先返回传递给它的确切对象。因此,在运行时,没有T可能违反强制转换的泛型参数的专门化。

又名,您将对象转换为自己的类型。

于 2013-02-25T16:55:08.540 回答
1

identityFunction() 只返回函数本身,用于不同的对象。

以下是一个使用示例:

String result = identityFunction().apply("Hello");

类型安全警告很重要。它存在是因为 IDENTITY_FUNCTION 的实现使得编译器无法保证函数返回与输入相同的类型。考虑以下替代实现:

private static UnaryFunction<Object> CONST_FUNCTION = new UnaryFunction<Object>() {
    public Object apply(Object arg) { return "Default"; } 
};

这个实现总是返回一个字符串,因此将它作为泛型数据类型上的一元函数返回显然是不安全的。

在我们的例子中(IDENTITY_FUNCTION),返回类型与输入类型相同的证明在实现内部。我们返回相同的实例,因此保证具有相同的类型。当你禁止类型安全警告时,建议用证明来证明它的合理性。

于 2013-02-25T16:58:45.633 回答