title: how to abstract(reduce) code using reflection to get field(Integer, Long, Float, Double) and do some calculation?
body: <p>I write a method to calculate QoQ generally.<br>
  My idea is to iterate all the fields and calculate if it's long , integer, float or double and set the field name and the result to a map.<br>
  It was easy to write this code, but I found it's too ugly :  </p>
  
  <pre class="lang-java prettyprint-override"><code>    public static &lt;T&gt; Map&lt;String, String&gt; calculateQoq(final T now, final T before) {
          final Field[] declaredFields = now.getClass().getDeclaredFields();
          if (ArrayUtils.isEmpty(declaredFields)) {
              return Collections.emptyMap();
          }
          final Map&lt;String, String&gt; map = new HashMap&lt;&gt;(declaredFields.length, 1);
          for (final Field f : now.getClass().getDeclaredFields()) {
              try {
                  f.setAccessible(true);
                  final Object a = f.get(before);
                  if (a instanceof Integer) {
                      final Integer beforeNum = (Integer)a;
                      if (beforeNum == null || beforeNum == 0) {
                          map.put(f.getName(), ZERO);
                          continue;
                      }
                      final Integer nowNum = (Integer) f.get(now);
                      if (nowNum == null) {
                          map.put(f.getName(), ZERO);
                          continue;
                      }
                      map.put(f.getName(), formatTwoFraction((nowNum - beforeNum) * 1.0 / beforeNum));
                  } else if (a instanceof Long) {
                      final Long beforeNum = (Long)a;
                      if (beforeNum == null || beforeNum == 0) {
                          map.put(f.getName(), ZERO);
                          continue;
                      }
                      final Long nowNum = (Long) f.get(now);
                      if (nowNum == null) {
                          map.put(f.getName(), ZERO);
                          continue;
                      }
                      map.put(f.getName(), formatTwoFraction((nowNum - beforeNum) * 1.0 / beforeNum));
                  } else if (a instanceof Double) {
                      final Double beforeNum = (Double)a;
                      if (beforeNum == null || beforeNum == 0) {
                          map.put(f.getName(), ZERO);
                          continue;
                      }
                      final Double nowNum = (Double) f.get(now);
                      if (nowNum == null) {
                          map.put(f.getName(), ZERO);
                          continue;
                      }
                      map.put(f.getName(), formatTwoFraction((nowNum - beforeNum) / beforeNum));
                  } else if (a instanceof Float) {
                      final Float beforeNum = (Float)a;
                      if (beforeNum == null || beforeNum == 0) {
                          map.put(f.getName(), ZERO);
                          continue;
                      }
                      final Float nowNum = (Float) f.get(now);
                      if (nowNum == null) {
                          map.put(f.getName(), ZERO);
                          continue;
                      }
                      map.put(f.getName(), formatTwoFraction((nowNum - beforeNum) / beforeNum));
                  }
              } catch (final Exception e) {
                  LOG.error("calculateQoq - get field failed - " + f.getName(), e);
              }
          }
          return map;
      }
  </code></pre>
  
  <p>I just repeat the nearly same logic four times, I try to use something like <code>&lt;T extends Number&gt; void doXXX(T before, T now)</code><br>
  But <code>Number</code> can't be calculated.<br>
  And Integer, Long and others don't have some common interface like <code>NumberEquals</code>(the default implementation of <code>equals</code> do type checking) or <code>Divideable</code>...<br>
  There is no macros in java too...<br>
  I tried some times emmmm but no solution yet.</p>
  
  <p>So I wonder is there any way to do abstraction and reduce this logic.  </p>