2017-02-07 8 views
0

У меня есть помощник ModelDecorator. Я хочу, чтобы иметь следующий публичный APIJava - Оценки класса public API

class ModelDecorator<T>{ 
    public static <T> ModelDecorator<T> create(Class<T> clazz); 
    public <SUPER> T from(SUPER fromInstance); 
} 

Таким образом, учитывая классы A, B расширяет A, он может быть использован, как это:

A a = new A(); 
B b = ModelDecorator.create(B.class).from(a); 

Но я хочу, чтобы иметь ограничения на Т и SUPER , поэтому я убеждаюсь, что только субклассы могут быть созданы с использованием API. В этот момент, я могу сделать:

C c = new C(); 
B b = ModelDecorator.create(B.class).from(c); 

Где B не наследуется от С.

Любые идеи? Благодаря

+1

Возможный дубликат [Почему параметр типа Java не имеет нижней границы?] (Http://stackoverflow.com/questions/4902723/why-cant-a-java-type-parameter-have-a- нижняя граница) – shmosel

ответ

3

Единственный способ я вижу сдерживая свой параметр типа T продлить параметр типа S, чтобы положить эти определения в определение класса:

public class ModelDecorator<S, T extends S> { 
    public static <S, T extends S> ModelDecorator<S, T> create(Class<T> clazz) { ... } 
    public T from(S instance) { ... } 
} 

С этими классами

class A {} 
class B extends A {} 
class C {} 

вам теперь можно написать следующий код:

A a = new A(); 
B b1 = ModelDecorator.<A, B> create(B.class).from(a); // compiles fine 

C c = new C(); 
B b2 = ModelDecorator.<C, B> create(B.class).from(c); // bound mismatch here 

У второго B теперь появилась ошибка компилятора.

К сожалению, теперь вы должны явно указать параметры типа, поскольку компилятор не может вывести тип A или C по простому вызову метода create(B.class).

+0

Это на самом деле так, как сейчас. Мне просто не нравится мой API так :(Я слишком придирчив? –

+0

Я не сказал ни слова об удобочитаемости или полезности. Возможно, вы пытаетесь решить проблему с помощью не соответствующей техники ([проблема XY] (http: //meta.stackexchange.com/questions/66377/what-is-the-xy-problem)) – Seelenvirtuose

+0

@Seelenvirtuose Я мог ошибаться, но 'create' - это' статический' метод. Будут 'S' и' T' в 'public static ModelDecorator create' быть тем же типом, что и в' public class ModelDecorator '? Если нет, будет использоваться другой параметр типа для метода' static' и «класс» - лучший вариант? – CKing