2015-05-27 4 views
2

Скажем, у меня есть общий интерфейс:смягчение Bound несовпадение

interface SomeInterface<T> { 
... 
} 

и две реализации:

конкретный один (возможно, оптимизированный для SpecificClass и его потомков):

class SpecificImplementation<T extends SpecificClass> implements SomeInterface<T> { 
... 
} 

и другое уловить все (возможно, которые могут обрабатывать все типы, но очень неэффективны):

class CatchAllImplementation<T> implements SomeInterface<T> { 
.... 
} 

И я хочу иметь общий метод, аналогичный следующий:

public <T> SomeInterface<T> getImplementation(Class<T> clazz) { 
    if(SpecificClass.class.isAssignableFrom(clazz)) 
    { 
    // do some specific stuff 

    ... 

    // get specific optimised implementation for SpecificClass and descendents 
    return new SpecificImplementation<T>(); // bound mismatch error here 
    } 
    else 
    { 
    // do other stuff 

    ... 

    // get inefficient catch all implementation in other cases 
    return new CatchAllImplementation<T>(); 
    } 
} 

Есть ли способ смягчения против связанной ошибки рассогласования? Какой-то трюк, чтобы заставить компилятор игнорировать его или подобное?

Мне не нужно привязывать параметр типа к конкретной реализации, но я бы предпочел сделать это.

+0

Разве вы не можете использовать что-то вроде 'класса SpecificImplementation реализует SomeInterface или' класс SpecificImplementation реализует SomeInterface '? – JimmyB

ответ

1
public class Main {  
    public <T> SomeInterface<T> getImplementation(Class<T> clazz) { 
     if(SpecificClass.class.isAssignableFrom(clazz)) 
     { 
      // do some specific stuff 

      // unchecked cast here... 
      return (SomeInterface<T>) getSpecificImplementation((Class<SpecificClass>) clazz); 
     } 
     else 
     { 
      // do other stuff 
      return new CatchAllImplementation<T>(); 
     } 
    } 

    private <T extends SpecificClass> SomeInterface<T> getSpecificImplementation(Class<T> clazz) { 
     return new SpecificImplementation<T>(); 
    } 

    public static void main(String[] args) { 
     Main m = new Main(); 
     SomeInterface<SpecificClass> implementation = m.getImplementation(SpecificClass.class); 

     System.out.println("Result: " + implementation.getClass()); 
     SomeInterface<Object> catchAll = m.getImplementation(Object.class); 

     System.out.println("Result: " + catchAll.getClass()); 

     SomeInterface<SpecificClassChild> implementationForChild = m.getImplementation(SpecificClassChild.class); 

     System.out.println("Result: " + implementationForChild.getClass()); 
    } 
} 

который печатает:

Result: class timo.generics.SpecificImplementation 
Result: class timo.generics.CatchAllImplementation 
Result: class timo.generics.SpecificImplementation 
+0

Будет ли это работать для классов параметров типов, которые расширяют SpecificClass? – PaddyD

+0

Не уверен, если я получу то, что вы имеете в виду, но я попробовал это: Создал «SpecificImplementationChild extends SpecificImplementation '. Верните новый экземпляр этого Ребенка в частный метод getSpecificImplementation. Это напечатало 'Результат: класс timo.generics.SpecificImplementationChild' вместо первой строки. – Timo

+0

Извините, что нужно прочитать более внимательно ... – Timo

0

Это потому, что SpecificImplementation нуждается в T, который расширяет SpecificClass.

Вы можете уйти с использованием SpecificImplementation без типа:

return new SpecificImplementation(); 

Лучшим решением было бы использовать наследование, а не с помощью если заявления.

+0

Я не уверен, как наследование поможет? Мне нужно использовать отражение, чтобы определить, какую универсальную реализацию использовать на основе класса параметра типа. – PaddyD

+0

Я не знаю о вашем случае использования, но ряд if-утверждений, которые проверяют экземпляр объекта, обычно является плохой практикой. – Robert

Смежные вопросы