Джава:разрешение времени компиляции и «наиболее конкретный метод»
-
15-11-2019 - |
Вопрос
Перегруженные функции 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));
}
}
Прочитав раздел JLS 15.12, я думаю, я понял...на этапе 2 (разрешена упаковка/распаковка, без переменных аргументов) сопоставления перегруженных методов при определении «наиболее конкретного метода» JLS говорит (фактически), что наиболее конкретным методом является тот, формальные параметры которого являются подтипами других применимых методов. , а также примитивы и объекты (например. int
и Integer
) никогда не являются подтипами друг друга.Так Integer
является подтипом Integer
, и int
является подтипом int
, но Integer
и int
несовместимы со сравнением подтипов, поэтому ни один из compute1()
/compute2()
пары имеют наиболее специфический метод.
(Тогда как в compute3()
и compute4()
метод с String
аргумент более конкретен, чем метод с Object
аргумент, поэтому программа печатает 6 и 8.)
Верны ли мои рассуждения?
Решение
Да, ваши рассуждения верны.
Другие советы
Если вы добавите еще один метод, который просто принимает примитивное целое число и упакованное целое число, он сможет решить, какой из методов следует вызывать:
int compute6(int i) { return 11;}
int compute6(Integer i){return 12;}
...
System.out.println(y.compute6(1));
Исходя из этого, я бы предположил, что это как-то связано с взаимодействием между различными параметрами, а не только с отношениями отдельных типов.