java泛型参数不能应用于特定类型

时间:2017-10-05 04:15:01

标签: java generics casting

public class Demo {
    public String work(String s) {
        return s;
    }

    public <T> T Test(T t) {
        // common work to do !!
        // .....
        // spec work to do 
        T result = work(t);
        return result;
    }
}

Test()首先要做一些共同的工作,然后针对不同类型的T进行具体的工作。 上面的代码导致编译器错误,我该怎么做? 非常感谢!

3 个答案:

答案 0 :(得分:0)

有很多事情可能导致您的代码无法在此编译;除了&#39 ;;&#39;,你从void方法返回一些东西。请发布您所面临的编译器错误,这将使潜在的响应者更加清楚。

答案 1 :(得分:0)

可能可能侥幸逃脱的是创建从T类型到(unary?)function的映射。然后,在test方法中,您可以查找类型T。如果函数是registerede,请应用:

public class Demo {
  private static final Map<Class<?>, UnaryOperator<?>> typeFuncs = new HashMap<>();
  static {{
    addTypeFunc(String.class, (String s) -> s); // Anonymous function.
    addTypeFunc(Integer.class, Demo::workInteger); // Function reference.
  }}

  private static <T> void addTypeFunc(Class<T> type, UnaryOperator<T> func) {
    typeFuncs.put(type, func);
  }

  private static Integer workInteger(Integer i) {
    return i;
  }

  public <T> T test(T t) {
    // common work to do !!
    // .....

    T result = null;
    UnaryOperator<T> operator = (UnaryOperator<T>) typeFuncs.get(t.getClass());
    if (operator != null) {
      result = operator.apply(t);
    }

    return result;
  }
}

请注意(UnaryOperator<T>)中的广告test只是安全的,因为我们可以完全控制typeFuncs地图中键和值类型之间的关系。

答案 2 :(得分:-1)

另一种方法是使用反射。请注意,反射是一种强大的工具,但它需要付出代价(性能)。执行测量以确定这是否是一个可行的解决方案是您的具体情况:

public class Demo {
  private String work(String s) {
    return s.toUpperCase();
  }

  private Boolean work(Boolean b) {
    return !b;
  }

  public <T> T test(T t) {
    // common work to do !!
    // .....

    // Now look-up "work" method for type T. Invoke if defined.
    T result = null;
    try {
      Class<T> tType = (Class<T>) t.getClass();
      Method work = Demo.class.getDeclaredMethod("work", tType);
      if (work.getReturnType() != tType) {
        throw new NoSuchMethodException("No `work` method for type: " + tType);
      }

      result = (T) work.invoke(this, t);
    } catch (NoSuchMethodException e) {
      // NOOP - or whatever.
    } catch (IllegalAccessException | InvocationTargetException e) {
      // Method invocation failed. Handle properly.
      e.printStackTrace();
    }

    return result;
  }
}