#java #generics
#Ява #дженерики
Вопрос:
У меня есть три похожих класса для разных типов.
public class IntClass { private int p1; private int p2; IntClass(int p1, int p2) { this.p1=p1; this.p2=p2; } int getP1() { return p1; } int getP2() { return p2; } } public class DoubleClass { private double p1; private double p2; DoubleClass(double p1, double p2) { this.p1=p1; this.p2=p2; } double getP1() { return p1; } double getP2() { return p2; } } public class StringClass { private String p1; private String p2; StringClass(String p1, String p2) { this.p1=p1; this.p2=p2; } String getP1() { return p1; } String getP2() { return p2; } } public class C4 { ... private IntClass c1; private DoubleClass c2; private StringClass c3; ... IntClass getIntClass() { return C1; } DoubleClass getDoubleClass() { return C2; } StringClass getStringClass() { return C3; } ... }
Где-то еще в кодовой базе у меня есть следующий фрагмент кода с 3 аналогичными методами.
... int a = getInt(C4::getIntClass, boolValue); double b = getDouble(C4::getDoubleClass, boolValue); String c = getString(C4::getStringClass, boolValue); ...
private int getInt(Supplierlt;IntClassgt; executable, boolean boolValue) { ... return boolValue? executable.get().getP1(): executable.get().getP2(); } private double getDouble(Supplierlt;DoubleClassgt; executable, boolean boolValue) { ... return boolValue? executable.get().getP1(): executable.get().getP2(); } private String getString(Supplierlt;StringClassgt; executable, boolean boolValue) { ... return boolValue? executable.get().getP1(): executable.get().getP2(); }
Я хотел написать универсальный метод getValue
вместо getInt
, getDouble
, getString
. Как мы можем это сделать?
Редактировать:- Не могу создать универсальный класс для IntClass
, DoubleClass
, StringClass
так как они также служат для некоторых других целей использования и находятся в другой библиотеке пакетов. Просто хотел с моей стороны провести рефакторинг кода, написав общий универсальный метод и удалив аналогичный избыточный код. Просто мысль!! Мы будем признательны за любые предложения, касающиеся конкретных случаев использования.
Ответ №1:
@Test public void test() { PairOflt;Stringgt; pairOfStr = new PairOflt;gt;("abc", "def"); PairOflt;Integergt; pairOfInt = new PairOflt;gt;(1, 2); PairOflt;Doublegt; pairOfDouble = new PairOflt;gt;(1.0, 2.0); Assertions.assertEquals(pairOfStr.getFirst(), getValue(pairOfStr, true)); Assertions.assertEquals(pairOfInt.getFirst(), getValue(pairOfInt, true)); Assertions.assertEquals(pairOfDouble.getFirst(), getValue(pairOfDouble, true)); } public class PairOflt;Tgt; { private T first; private T second; public PairOf(T first, T second) { this.first = first; this.second = second; } public T getFirst() { return first; } public T getSecond() { return second; } } public lt;Tgt; T getValue(PairOflt;Tgt; t, boolean first) { return first ? t.getFirst() : t.getSecond(); }
С помощью числа вы можете привести к примитиву методом:
getValue(pairOfInt, true).intValue(); getValue(pairOfDouble, true).doubleValue();
Ответ №2:
Попробуйте это:
public class GenericClasslt;Tgt; { private T p1; private T p2; GenericClass(T p1, T p2) { this.p1=p1; this.p2=p2; } T getP1() { return p1; } T getP2() { return p2; } }
private T getValue(Supplierlt;GenericClasslt;Tgt;gt; executable, boolean boolValue) { return boolValue ? executable.get().getP1(): executable.get().getP2(); }
Ответ №3:
Ну, вам нужно начать с универсального класса и сделать что-то вроде:
public class PairOflt;Tgt; { private T first; private T second; public PairOf(T first, T second) { this.first = first; this.second = second; } public T getFirst() { return first; } public T getSecond() { return second; } }
Затем вы можете использовать этот класс вместо ваших конкретных классов точно так же, как и раньше.
Комментарии:
1. Определенно, это путь вперед! Но я могу создать универсальный класс, как было предложено. Эти классы служат и для других целей, о которых я забыл упомянуть.
2. Конечно, вам придется немного адаптировать свой класс C4, но это не должно быть проблемой. Если вы застряли, напишите комментарий, и я с радостью помогу.
3. Можем ли мы использовать отражения или объекты базового класса и типы отливок для достижения этой цели?