Java中的伪重载

Java中的伪重载,java,generics,enums,overloading,Java,Generics,Enums,Overloading,考虑以下功能: public static <T> T doSomething(Document doc, String xpath, Class<T> returnType); 不起作用,因为returnType不是类。但是,您也无法通过Class.asSubclass()将returnType塑造成那样(至少在不使用不安全的强制转换的情况下,我们正试图避免这种情况) 似乎您也无法重载doSomething(),以执行特定于枚举的操作-即 public static

考虑以下功能:

public static <T> T doSomething(Document doc, String xpath, Class<T> returnType);
不起作用,因为
returnType
不是
。但是,您也无法通过
Class.asSubclass()
returnType
塑造成那样(至少在不使用不安全的强制转换的情况下,我们正试图避免这种情况)

似乎您也无法重载
doSomething()
,以执行特定于枚举的操作-即

public static <T extends Enum<T>> T doSomething(Document doc, String xpath, Class<T> returnType);
publicstatictdosomething(文档文档、字符串xpath、类returnType);
因为从运行时的角度来看,这实际上是“相同的签名”


所以,问题是,有没有一种方法可以在一个方法中安全地完成所有这些工作,或者我需要一个单独的方法来专门处理枚举还是使用不安全的强制转换?

我对这个问题很感兴趣,可以尝试一下。我没有成功,但我认为值得在这里分享这一尝试,以便进一步讨论

interface Evaluator {
  <T> T evaluate(String path, Class<? extends T> type);
}


final class Attempt implements Evaluator {
  @Override
  public <T> T evaluate(String path, Class<? extends T> type) {
    final Object result = evaluatePath(path, type);
    return type.cast(type.isEnum() ?
                     valueOf(type.asSubclass(Enum.class), (String)result) :
                     result);
  }


  private static Object evaluatePath(String path, Class<?> type) {
    /* This doesn't actually do anything meaningful, but that doesn't matter for now.
       Presumably it would make a call to something like XPath#evaluate().
     */
    return path;
  }


  private static <T extends Enum<T>> T valueOf(Class<T> type, String name) {
    return Enum.valueOf(type, name);
  }
}
接口计算器{
T求值(字符串路径,类类型){
/*这实际上并没有做任何有意义的事情,但现在这并不重要。
大概它会调用XPath#evaluate()之类的函数。
*/
返回路径;
}
私有静态T值(类类型、字符串名称){
返回Enum.valueOf(类型、名称);
}
}
此代码在键入编译器时通过IntelliJ IDEA,但在提交到真正的javac时失败:

[unchecked]未选中的方法调用:
尝试中的valueOf(java.lang.Class,java.lang.String)应用于
(java.lang.Class、java.lang.String)
我发现错误消息令人费解,我认为这是将原始类型
Enum
(如
Class
)传递给寻找参数化类型的方法的一个表达不好的结果


为了确认这里需要什么样的令人厌恶的施法,我鼓励其他人编辑(或复制和扩充)上述代码,以说明所需的更改。

使用不安全的施法。Java不能证明它是安全的,但你可以。@KelvinChung不要使用
String.class.cast
它有点难读,完全没有必要。只需使用普通的casttry=>@SuppressWarnings(“未选中”)。你的方法工作得很好。是的,我希望它可以顺利运行,但最初的问题是寻找一些方法来写这个,而不诉诸任何警告抑制。好吧,再看一遍,它提到了“不安全的施法”。在这种情况下,我们面临着一个可抑制的警告,但我们相信忽略它是安全的。
interface Evaluator {
  <T> T evaluate(String path, Class<? extends T> type);
}


final class Attempt implements Evaluator {
  @Override
  public <T> T evaluate(String path, Class<? extends T> type) {
    final Object result = evaluatePath(path, type);
    return type.cast(type.isEnum() ?
                     valueOf(type.asSubclass(Enum.class), (String)result) :
                     result);
  }


  private static Object evaluatePath(String path, Class<?> type) {
    /* This doesn't actually do anything meaningful, but that doesn't matter for now.
       Presumably it would make a call to something like XPath#evaluate().
     */
    return path;
  }


  private static <T extends Enum<T>> T valueOf(Class<T> type, String name) {
    return Enum.valueOf(type, name);
  }
}
[unchecked] unchecked method invocation:
  <T>valueOf(java.lang.Class<T>,java.lang.String) in Attempt is applied to
  (java.lang.Class<capture#474 of ? extends java.lang.Enum>,java.lang.String)