Рефакторинг методов, аналогичных универсальному методу в Java

#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. Можем ли мы использовать отражения или объекты базового класса и типы отливок для достижения этой цели?