Java: разрешение во время компиляции и «самый специфический метод» - PullRequest
5 голосов
/ 19 мая 2011

Перегруженные функции compute1(), compute2() и compute5() вызывают ошибки компиляции, если вы попытаетесь использовать их ниже:

package com.example.test.reflect;

class JLS15Test2
{
    int compute1(Object o1, Integer i, Integer j)         { return 1; }
    int compute1(String s1, Integer i, int j)             { return 2; }

    int compute2(Object o1, Integer i, int j)             { return 3; }
    int compute2(String s1, Integer i, Integer j)         { return 4; }

    int compute3(Object o1, Integer i, int j)             { return 5; }
    int compute3(String s1, Integer i, int j)             { return 6; }

    int compute4(Object o1, Integer i, Integer j)         { return 7; }
    int compute4(String s1, Integer i, Integer j)         { return 8; }

    int compute5(Object o1, Integer i, Object j)          { return 9; }
    int compute5(String s1, Integer i, int j)             { return 10; }


    public static void main(String[] args) 
    {
        JLS15Test2 y = new JLS15Test2();

        // won't compile:
        // The method compute1(Object, Integer, Integer) is ambiguous 
        // for the type JLS15Test2
        // System.out.println(y.compute1("hi", 1, 1));

        // Neither will this (same reason)
        // System.out.println(y.compute2("hi", 1, 1));
        System.out.println(y.compute3("hi", 1, 1));
        System.out.println(y.compute4("hi", 1, 1));

        // neither will this (same reason)
        // System.out.println(y.compute5("hi", 1, 1));
    }
}

После прочтения раздела 15.12 JLS, я думаю, что я понимаю ... на этапе 2 (бокс / распаковка разрешен, никаких переменных) сопоставления перегруженных методов при определении «наиболее конкретного метода», JLS говорит (в действительности) что наиболее конкретным методом является тот, формальные параметры которого являются подтипами других применимых методов, а примитивы и объекты (например, int и Integer) никогда не являются подтипами друг друга. Таким образом, Integer является подтипом Integer, а int является подтипом int, но Integer и int являются несовместимыми сравнениями подтипов w / r / t, поэтому ни один из compute1() / У compute2() пар самый специфический метод.

(В то время как в compute3() и compute4() метод с аргументом String более специфичен, чем метод с аргументом Object, поэтому программа печатает 6 и 8.)

Верны ли мои рассуждения?

Ответы [ 2 ]

0 голосов
/ 19 мая 2011

Если вы добавите другой метод, который просто принимает примитив int и целое число в штучной упаковке, он может определить, какой метод является правильным для вызова:

int compute6(int i) { return 11;}
int compute6(Integer i){return 12;}
...
System.out.println(y.compute6(1));

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

0 голосов
/ 19 мая 2011

Да, ваши рассуждения верны.

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