Стирание типа Java и перегрузка? - PullRequest
3 голосов
/ 22 сентября 2011

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

Ответы [ 3 ]

4 голосов
/ 22 сентября 2011

Механизм перегрузки работает во время компиляции, то есть, какой метод вызывается, определяется при компиляции классов, а не при запуске программы.

Поскольку типы времени выполнения не могут (в общем) быть известныво время компиляции такой фрагмент

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

приведет к вызову method, который принимает Object в качестве аргумента, поскольку Object является типом времени компиляции из o.

(Это не имеет ничего общего с стиранием типов или обобщениями.)

1 голос
/ 22 сентября 2011

Единственный метод, который вы на самом деле реализуете для Converter, это convert (Object source), потому что вы указали тип-параметра Object в:

Converter<Object, Sku>

Два других метода convert с аргументами String и 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.
0 голосов
/ 22 сентября 2011

Как объяснили другие, это связано не со стиранием, а с тем фактом, что 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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...