Honestly, I'm not even sure whether that title makes sense. Hopefully the code following will explain the issue at hand.
package what.ever.you.like;
import java.util.function.UnaryOperator;
class SelfTypeTemplates {
public static <SELF extends AbstractSelfType> UnaryOperator<SELF> simpleBound() {
return self -> self;
}
public static <SELF extends AbstractSelfType<SELF>> UnaryOperator<SELF> boundWithGenericType() {
return self -> self;
}
}
class ConcreteSelfType extends AbstractSelfType<ConcreteSelfType> {
public ConcreteSelfType() {
super(ConcreteSelfType.class);
}
public ConcreteSelfType applySimpleBound() {
// How to get rid of the type cast?
return (ConcreteSelfType) SelfTypeTemplates.simpleBound().apply(this);
}
public ConcreteSelfType applyBoundWithGenericType() {
// Compile error because `this` is ConcreteSelfType, but required is SELF
return SelfTypeTemplates.boundWithGenericType().apply(this);
}
}
class AbstractSelfType<SELF extends AbstractSelfType<SELF>> {
protected final SELF myself;
protected AbstractSelfType(final Class<?> type) {
this.myself = (SELF) type.cast(this);
}
}
My issue is with the two methods applySimpleBound()
and applyBoundWithGenericType()
. The former is compiling fine, but needs explicit casting, which is what I'd like to get rid of. The later does not compile, because .apply(this)
requires a type SELF
but provided is ConcreteSelfType
.
So my question is, how do I specify the signature of a method in SelfTypeTemplates
to return an UnaryOperator<SELF>
so that invoking the returned function ( .apply(this)
), does not need casting in the client code (ie ContreteSelfType
)?
Tried to play with different bounds in the generic and return type. Haven't found a working version without type casting.
Sometimes the compiler cannot infer the correct type for what ever reason. To work around this issue you can specify it like this:
class ConcreteSelfType extends AbstractSelfType<ConcreteSelfType> {
public ConcreteSelfType() {
super(ConcreteSelfType.class);
}
public ConcreteSelfType applySimpleBound() {
// How to get rid of the type cast?
return SelfTypeTemplates.<ConcreteSelfType>simpleBound().apply(this);
}
public ConcreteSelfType applyBoundWithGenericType() {
// Compile error because `this` is ConcreteSelfType, but required is SELF
return SelfTypeTemplates.<ConcreteSelfType>boundWithGenericType().apply(this);
}
}
Both options compile this way and you don't need a cast.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.