Skip to content
Advertisement

why is this still need to cast in java?

error

public class DefaultLiteProcessScopeFactory<S extends DefaultLiteProcessScope> implements LiteProcessScopeFactory<S> {
    @Override
    public S build() {
        return new DefaultLiteProcessScope();
    }
}

right

public class DefaultLiteProcessScopeFactory<S extends DefaultLiteProcessScope> implements LiteProcessScopeFactory<S> {
    @Override
    public S build() {
        return (S) new DefaultLiteProcessScope();
    }
}

DefaultLiteProcessScope extends DefaultLiteProcessScope,but it is till need to be cast?why?

Advertisement

Answer

What you are doing here is wrong. You want to return some subtype of DefaultLiteProcessScope from the build method. However, you hard code the return type like this: new DefaultLiteProcessScope(). Now think of a slightly contrived example like this.

static class SubType extends DefaultLiteProcessScope {
        
}

And a client code that follows.

final LiteProcessScopeFactory<SubType> f = new DefaultLiteProcessScopeFactory<>();
final SubType result = f.build();

Now, since you have hard-coded the return type your compiler can’t vouch for the type safety of the code. I wanted it to return the sub type, however you have hard-coded the super-type instead. So, it asks you to add an explicit cast, which is fair, isn’t it? In fact, this cast fails at runtime throwing a java.lang.ClassCastException since super type DefaultLiteProcessScope cannot be cast to the subtype SubType.

How to fix.

A much better approach would be to pass in a supplier to your build method as an argument like so.

static class DefaultLiteProcessScopeFactory<S extends DefaultLiteProcessScope> implements LiteProcessScopeFactory<S> {
    @Override
    public S build(Supplier<S> s) {
        return s.get();
    }
}

static interface LiteProcessScopeFactory<S> {
    S build(Supplier<S> s);
}

Here’s the new client code.

final LiteProcessScopeFactory<SubType> f = new DefaultLiteProcessScopeFactory<>();
final SubType result = f.build(SubType::new);
Advertisement