javaoverloadingstrong-typing

let compiler do the work by overloading methods doesn't work


Suppose I have the following class Structure

public interface Searchable{

    public boolean matches(String text);

}

public abstract class AbstractSearchable implements Searchable{

    private String name;


    public boolean matches(String text){
        return null != name && name.startswith(text);
    }
}

Most of my domain Objects inherit from AbstractSearchable, but there are a few which are only Searchable and implement their own behavior.

Then I have a Test as Following:

public class SearchableTest<T extends Searchable>{
    public void testSearchable(){
        //get an instance which is either Searchable or AbstractSearchable
        T item = getSomeTestItem();
        checkItem(item);
    }

    public void checkItem(Searchable searchable){
        throw new UnsupportedOperationException("Please implement your own check for Searchable and Override checkItem(Searchable)!");
    }

    public void checkItem(AbstractSearchable item){
        //here i can Implement the Test using the name from AbstractSearchable
        //... implementation
    }
}

I thougth, that if the Return of getSomeTestItem is AbstractSearchable the compiler will find this out and passes it to the 'right' checkItem method. I read somewhere ( I really forgot where), taht the Java compiler always figures out kind of the 'best fit' (meaning TestItem is actually 'more' AbstractSearchable than Searchable). Unfortunately it does not, and all AbstractSearchables gets passed to the 'wrong' checkItem` method.

I'm aware of the quickfix

public void checkItem(Searchable searchable){
    if (searchable instanceof AbstractSearchable){
        checkItem((AbstractSearchable)searchable);
    } else {
        throw new UnsupportedOperationException("Please implement your own check for Searchable and Override checkItem(Searchable)!");
    }
}

but I really hate instanceof checks. Is there something I can do, to make this work?


Solution

  • As you say the compiler tries to find the best fit - but the kind of object returned by getTestItem will only be known at runtime and you only declare it to be a T extends Searchable. So the best fit you can find at compile-time is checkItem(Searchable searchable) :-(