Why is it safe to suppress this unverified warning?

Consider the UnaryFunction interface defined in the chapter Effective Java .

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

and the following code to return 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 safe to share one instance across all types. @SuppressWarnings("unchecked") public static <T> UnaryFunction<T> identityFunction() { return (UnaryFunction<T>) IDENTITY_FUNCTION; } 

Why is different from IDENTITY_FUNCTION to (UnaryFunction<T>) safe?

The book talks about this question that I ask, but I cannot follow the logic here. Where do we call the apply function that performs the authentication operation? I got confused because it is a function that returns the same object that it passed without changing anything.

Listing IDENTITY_FUNCTION on (UnaryFunction<T>) generates a warning without warning, because UnaryFunction<Object> not UnaryFunction<T> for each T But the identity function is special: it returns its argument unmodified, so we know that it is typical to use this as UnaryFunction<T> regardless of the value of T Therefore, we can confidently suppress the unverified throw warning that this cast creates. Once we do this, the code compiles without error or warning.

+7
source share
3 answers

Casting is safe only because the identification function returns the exact object that was transferred to it in the first place. Thus, at run time, there is no specialization in the general parameter T , which can violate the cast.

Aka, you throw the object as your own type.

+3
source

With erase type

 T apply(T arg); 

in fact

 Object apply(Object arg); 

Now for identity

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

we can assume that it is always correct (equivalent to y = x; ).

(Very pragmatic.)

+3
source

identityFunction () simply returns the function itself, which will be used for different objects.

Below is an example of use:

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

A type safety warning is important. This is there because IDENTITY_FUNCTION is implemented in such a way that the compiler cannot guarantee that the function returns the same type as the input. Consider the following alternative implementation:

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

This implementation always returns a string, so it is clearly unsafe to return it as a unary function in a common data type.

In our case (IDENTITY_FUNCTION), the proof that the return type matches the input type is inside the implementation. We return the same instance, so it has the same type. When you suppress type safety warnings, it is recommended that you prove this with evidence.

+1
source

All Articles