I am trying to figure out if there is a way to avoid the unchecked cast in this function (using Java 7):
private static <O> ValueValidator<O> newForAlways(Always valid_orInvalid) {
@SuppressWarnings("unchecked")
ValueValidator<O> vldtr = (ValueValidator<O>)(valid_orInvalid == Always.VALID
? newForAlwaysValid()
: newForAlwaysInvalid());
return vldtr;
}
Here are the signatures of the two functions being returned:
private static <O> ValueValidator<O> newForAlwaysValid() {
private static <O> ValueValidator<O> newForAlwaysInvalid() {
(And here's the Always
enum, which is just a boolean substitute:
enum Always {VALID, INVALID;};
)
All three functions have the same return type and contain an unbounded generic. These two questions explain why it happens, although both are about bounded generics:
- Why doesn't the ternary operator like generic types with bounded wildcards?
- Generics compilation error with ternary operator in Java 8, but not in Java 7
So even though this works
ValueValidator<Integer> intVldtr = Test.<Integer>newForAlwaysValid();
this doesn't:
private static <O> ValueValidator<O> newForAlways(Always valid_orInvalid) {
return (valid_orInvalid == Always.VALID
? <O>newForAlwaysValid()
: <O>newForAlwaysInvalid());
}
C:\java_code\Test.java:15: error: illegal start of expression
? <O>newForAlwaysValid()
...and 8 more similar errors...
And neither does this:
private static <O> ValueValidator<O> newForAlways2(Always valid_orInvalid) {
return (valid_orInvalid == Always.VALID
? newForAlwaysValid()
: newForAlwaysInvalid());
}
C:\java_code\Test.java:15: error: incompatible types
? newForAlwaysValid()
^
required: ValueValidator<O>
found: ValueValidator<Object>
where O is a type-variable:
O extends Object declared in method <O>newForAlways2(Always)
So, to repeat the question: Is there any alternative to the unchecked cast? (I'm using Java 7.)
public class Test {
public static void main(String[] ignored) {
ValueValidator<Integer> intVldtr = Test.<Integer>newForAlwaysValid();
intVldtr = Test.<Integer>newForAlways(Always.VALID);
}
private static <O> ValueValidator<O> newForAlways(Always valid_orInvalid) {
@SuppressWarnings("unchecked")
ValueValidator<O> vldtr = (ValueValidator<O>)(valid_orInvalid == Always.VALID
? newForAlwaysValid()
: newForAlwaysInvalid());
return vldtr;
}
private static <O> ValueValidator<O> newForAlwaysValid() {
return (new AlwaysValid<O>());
}
private static <O> ValueValidator<O> newForAlwaysInvalid() {
return (new AlwaysInvalid<O>());
}
}
enum Always {VALID, INVALID;};
abstract class ValueValidator<O> {
public abstract boolean isValid(O to_validate);
}
class AlwaysValid<O> extends ValueValidator<O> {
public boolean isValid(O to_validate) {
return true;
}
}
class AlwaysInvalid<O> extends ValueValidator<O> {
public boolean isValid(O to_validate) {
return false;
}
}