【问题标题】:Java Type Erasure and Overloading?Java类型擦除和重载?
【发布时间】:2011-09-22 08:36:34
【问题描述】:

谁能简单解释一下为什么在下面的类中,当我传入String、Integer或UUID时,只使用了以Object为参数的方法重载?

public final class SkuHydratingConverter implements Converter<Object, Sku> {
    @Autowired
    private SkuService skuService;


    /**
     * Default implementation, that errs as we don't know how to convert from
     * the source type.
     */
    public Sku convert(Object source) throws IllegalArgumentException {
        throw new IllegalArgumentException("Could not convert to Sku");
    }


    public Sku convert(String source) throws IllegalArgumentException {
        return convert(Integer.valueOf(source));
    }


    public Sku convert(Integer source) throws IllegalArgumentException {
        return skuService.get(source);
    }


    public Sku convert(UUID source) throws IllegalArgumentException {
        return skuService.get(source);
    }
}

本来我想在一个类中实现Converter&lt;?, ?&gt; 3次,但我很快发现这是不可能的。

【问题讨论】:

  • 你如何访问这个方法?能给个代码示例吗?

标签: java generics spring-mvc overloading type-erasure


【解决方案1】:

重载机制在编译时起作用,即在编译类时决定调用哪个方法,而不是在运行程序时决定。

由于在编译时(通常)无法知道运行时类型,因此像这样的 sn-p

Object o = "some string";
method(o);

将导致调用以Object 作为参数的method,因为Objectocompile-time type

(这与类型擦除或泛型无关。)

【讨论】:

    【解决方案2】:

    您实际为 Converter 实现的唯一方法是 convert(Object source),因为您在以下位置提供了类型参数 Object:

    Converter<Object, Sku>
    

    只有当您直接使用实例(而不是通过接口)时才能调用其他两个带有字符串和 UUID 参数的转换方法。这两个方法不会覆盖任何东西,它们会重载。

    Converter con = new SkuHydratingConverter();
    con.convert(new String());//calls convert(Object), it does not know about any other method
    
    SkuHydratingConverter con2 = new SkuHydratingConverter();
    con2.convert(new String()); //calls convert(String), because it is one with best matching type of argument.
    

    【讨论】:

      【解决方案3】:

      正如其他人所解释的,这与擦除无关,而是convert(Object source) 在编译时绑定的事实。如果你在每个前面加上@Override,其余部分都会出错,表明只有那个方法覆盖了超类方法。

      你需要的是实际类型的运行时检查:

      public Sku convert(Object source) throws IllegalArgumentException
      {
          if (source instanceof String) {
              return convert((String) source);
          } else if (source instanceof ...) {
          } else // none match, source is of unknown type
          {
              throw new IllegalArgumentException("Could not convert to Sku, unsuported type " + source.getClass());
          }
      }
      
      }
      

      其他的convert 方法应该是private

      【讨论】:

        猜你喜欢
        • 2016-03-31
        • 1970-01-01
        • 1970-01-01
        • 2023-04-07
        • 1970-01-01
        • 1970-01-01
        • 2012-01-17
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多