2016-11-21 3 views
-2

Я хочу создать интерфейс, где я могу это сделать.Правильный способ создания универсального метода интерфейса?

public interface Getter { 
    T get(String location); 
} 

public class IntegerGetter { 
    Integer get(String location) { 
    Object x = foo(location); 
    if (!(x instanceOf Integer)) { throw Exception } 
    return (Integer) x; 
    } 
} 

Каков правильный способ организации дженериков, чтобы сделать эту работу? Один из вариантов, похоже, должен сделать T параметром типа самого интерфейса, например. Getter<T>, IntegerGetter<Integer>, но поскольку параметр используется только для одного метода, для него более разумным является параметр метода. Тем не менее, мне сообщили, что просто наличие параметра типа является типом возвращаемого метода опасным, например. <T> T get.

+1

Что такое 'foo' здесь? – flakes

+2

", но поскольку параметр используется только для одного метода, для него более разумным является параметр метода." Нет, это не имеет смысла. Используйте 'Getter ' и 'IntegerGetter реализует Getter '. – bradimus

+0

@bradimus пример, который я предоставил, был минимальным, но на самом деле я строю что-то, что имеет кучу других методов, не связанных с типом. В этом случае метод не будет использоваться 95% пользователей этого класса, но они все равно должны будут предоставить параметр типового типа. Должно было сделать это яснее. Вы все еще говорите, что это не имеет никакого смысла? –

ответ

1

Мне сообщили, что только с параметром типа возвращаемый тип метода является опасным, например. <T> T get.

Это не более опасно, чем то, что у вас уже есть.

Упрощая свой IntegerGetter немного:

class IntegerGetter { 
    Integer get(String location) { 
    return (Integer) foo(location); 
    } 
} 

Вы можете определить эквивалентный класс для String с:

class StringGetter { 
    String get(String location) { 
    return (String) foo(location); 
    } 
} 

Предполагая, что foo(String) тот же самый метод в этих двух классов, что она возвращает результат основан только на location, и он не возвращает null, по крайней мере одна из следующих строк не сработает:

Integer i = new IntegerGetter().get("hello"); 
String s = new StringGetter().get("hello"); 

с foo("hello") не может быть как String, так и Integer.

Таким образом, вы можете также просто иметь единственную реализацию:

class SimplerGetter { 
    <T> T get(String location) { 
    return (T) foo(location); 
    } 
} 

который подведет в одних и тех же условиях, что и с отдельными классами.

Integer i = new SimplerGetter().get("hello"); 
String s = new SimplerGetter().get("hello"); 
+0

Есть разница, если вы не указываете тип при вызове, например. 'Object o = new SimplerGetter(). Get (" hello ");'. – shmosel

1

Вы в основном реализуете интерфейс, похожий на Supplier. Вы можете взять это как ссылку. Интерфейс должен быть введен с параметром T, в противном случае метод get может использоваться в контексте вызова, где он может возвращать объект любого типа.

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