Переопределение статического метода <K, V> - PullRequest
0 голосов
/ 09 мая 2018

У нас есть метод для выполнения сравнения двух универсальных объектов:

    public static <K, V> Diff<K, V> check(K key, V act, V exp) {
        Diff<K, V> d = null;
        System.out.println(act.getClass());
        System.out.println(exp.getClass());
        // null checks
        if (exp == null && act == null) {
            // both null, so no difference
        } else if (exp == null) {
            d = new Diff<>(key, null, act);
        } else if (act == null) {
            d = new Diff<>(key, exp, null);
        } else {
            // compare the entries
            if (!exp.equals(act)) {
                d = new Diff<>(key, exp, act);
            }
        }

        return d;
    }

Проблема в том, что для дат (java.sql.Date), то есть иногда дата вместо просто MM / dd / yyyy может иметь MM / dd / yyyy чч: мм, тогда как у другой ее нет, поэтому она не обрабатывается их как равных. Я хочу, чтобы они были равны, если даты совпадают (меня не волнуют часы, минуты, секунды).

Итак, я попытался создать новый метод:

    public static <K, V> Diff<K, java.sql.Date> check(K key, java.sql.Date act, java.sql.Date exp) {
        Diff<K, java.sql.Date> d = null;

        // null checks
        if (exp == null && act == null) {
            // both null, so no difference
        } else if (exp == null) {
            d = new Diff<>(key, null, act);
        } else if (act == null) {
            d = new Diff<>(key, exp, null);
        } else {
            // compare the entries
            if (!exp.toString().equals(act.toString())) {
                d = new Diff<K, java.sql.Date>(key, exp, act);
            }
        }

        return d;
    }

по какой-то причине он не позволил бы мне сказать публичную статичность. Во всяком случае, это не дает никаких ошибок компилятора, но когда программа, я вижу, вызывается оригинальный метод. Вы можете увидеть в оригинальном методе я печатаю классы и их значения

class java.sql.Date
class java.sql.Date

так почему мой специализированный метод не вызывается, а общий вызывается?

Это класс (часть его):

public static class Diff<K, V> {
    private K key;
    private V exp, act;
    ...
    ...
}

(я перечислил данные, здесь есть много других методов, которые я показываю ...)

Вот вызывающая функция. На карте есть несколько строк. Некоторые длинные, некоторые строковые, некоторые sql даты. Ключ всегда является строкой, но во многих других местах это тоже может вызываться, что может иметь другие типы данных для ключа.

public static <K, V> List<Diff<K, V>> MapComparison(Map<K, V> map1, Map<K, V> map2) {
    List<Diff<K, V>> result = new LinkedList<Diff<K, V>>();

    // null checks
    if (map1 == null) {
        map1 = new HashMap<K, V>();
    }
    if (map2 == null) {
        map2 = new HashMap<K, V>();
    }

    HashSet<K> allKeys = new HashSet<K>();
    allKeys.addAll(map1.keySet());
    allKeys.addAll(map2.keySet());

    for (K key : allKeys) {
        V exp = map1.get(key);
        V act = map2.get(key);
        Diff<K, V> d = Diff.check(key, act, exp);
        if (d != null) {
            result.add(d);
        }
    }

    return result;
}

вызывает сопоставление карты:

public static DiffListMap doComparison(RowList exp, RowList act, String keyName) {
    DiffListMap ret = new DiffListMap();
    DiffList diffs;

    // Loop through each expected row.
    for (Row exp_row : exp) {
        Object key = exp_row.get(keyName);
        diffs = null;
        boolean found = false;
        // Look for the corresponding actual row
        // using the unique key
        for (Row act_row : act) {
            if (act_row.get(keyName).equals(key)) {
                // If the correct one is found, do the comparison
                found = true;
                diffs = new DiffList(MapComparison(exp_row, act_row));
                // remove the row from the actual results.
                act.remove(act_row);
                break;
            }
        }

и FYI

public static class Row extends HashMap<String, Object> {
    private static final long serialVersionUID = 1L;
}

1 Ответ

0 голосов
/ 09 мая 2018
public static <K, V> List<Diff<K, V>> MapComparison(Map<K, V> map1, Map<K, V> map2) {
    // ...
    V exp = map1.get(key);
    V act = map2.get(key);
    Diff<K, V> d = Diff.check(key, act, exp);
    // ...

Сайты вызовов связаны в время компиляции . Компилятор никогда не будет связывать этот вызов Diff.check с вашей новой перегрузкой, потому что он не знает и не заботится о том, что V может быть связан с java.sql.Date во время выполнения. Он знает только, что K и V являются некоторыми типами, производными от Object, поэтому он привязывается к единственному методу, который может: Diff<K, V> check(K, V, V).

...