Почему int invicitly применяется для float, а не double при вызове конструктора?

Я написал этот тестовый код

public class ConstructorTestApplication {

    private static String result;


    public static void main(String[] args) {

        ConstructorTest test1 = new ConstructorTest(0);
        System.out.println(result);
    }

    private static class ConstructorTest {

        public ConstructorTest(double param){
            result = "double constructor called!";
        }
        public ConstructorTest(float param) {
            result = "float constructor called!";
        }


    }
}

Результат был

float constructor called!

Почему был создан конструктор float вместо двойного конструктора? Является ли эта часть динамического поиска методов?

Ответ 1

ConstructorTest(float param) - это наиболее специфический метод из двух конструкторов, поскольку метод с аргументом double может принимать любое значение float, но противоположное неверно.

JLS 15.12.2.5:

15.12.2.5. Выбор наиболее конкретного метода

Если более чем один метод-член доступен и применим к необходимо вызвать один из них, чтобы обеспечить дескриптор для отправки времени выполнения. Программирование на Java язык использует правило, в котором выбран наиболее специфический метод.

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

Ответ 2

Я представляю JLS 5.3. Метод Invocation Conversion и 5.1.2. Расширение примитивного преобразования

19 конкретных преобразований на примитивных типах называются расширяющимися примитивные преобразования:

byte для коротких, int, long, float или double

short для int, long, float или double

char в int, long, float или double

int для long, float или double

долго плавать или удваивать

float, чтобы удвоить

По сути, поплавки ставятся в приоритет над удвоениями при перегрузке метода при выполнении литья.