假设我有以下类结构
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);
}
}
我的大多数域对象都继承自AbstractSearchable
,但有一些只有Searchable
并且实现了自己的行为。
然后我有一个测试如下:
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
}
}
我认为,如果getSomeTestItem
的返回是AbstractSearchable,编译器会发现它并将其传递给'right'checkItem
方法。我在某处阅读(我真的忘了在哪里),Java编译器总是想出“最适合”的类型(意思是TestItem实际上比搜索更“抽象”)。不幸的是,它没有,并且所有AbstractSearchables
都被传递给'错误的'checkItem`方法。
我知道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)!");
}
}
但我真的讨厌instanceof
次检查。我有什么办法可以做到这一点吗?
答案 0 :(得分:2)
正如您所说编译器试图找到最合适的 - 但getTestItem
返回的对象类型只会在运行时被识别,您只能将其声明为{{ 1}}。因此,您在编译时可以找到的最佳拟合是T extends Searchable
: - (
答案 1 :(得分:0)
对于所需的类结构,我认为没有办法达到你想要的,因为T
被声明为extends Searchable
,可以是Searchable
或AbstractSearchable
,并根据此信息找到正确的方法,即您描述和不想要的行为。
为了避免此问题,您可能希望重构类以避免继承AbstractSearchable
,而是委托matches()
调用提供给域对象或服务中的某些实现。< / p>