Преобразование одного примитивного типа в другой в Java - PullRequest
0 голосов
/ 01 сентября 2018

В следующем фрагменте кода

  class Main {

    void m1(double x){

        System.out.println("double");
    }

    void m1(float x){

        System.out.println("float");
    }

    void m1(long x){

        System.out.println("long");
    }

    void m1(byte x){

        System.out.println("byte");
    }

    void m1(short x){

        System.out.println("short");
    }

    void m1(int x){

        System.out.println("int");
    }


    public static void main(String[] args) {

      Main m = new Main();
         m.m1(1);
    }
}

Почему вывод "int" вместо "byte" или "long", "short", "float" или "double"?

Если после автоматического преобразования из "byte" -> "short" -> "int" -> "long" -> "float" -> "double", вывод должен вывести "double", верно?

(https://www.geeksforgeeks.org/type-conversion-java-examples/)

Ответы [ 3 ]

0 голосов
/ 01 сентября 2018

По определению, этот примитивный литерал имеет тип int. Любой числовой литерал без десятичной точки имеет тип int , если только вы не введете в него значение l / L: 1L, чтобы превратить его в длинную. Там нет 1 "байта" литерала, вам нужно идти (byte) 1, чтобы добраться туда.

Компилятор ищет лучшее соответствие и использует тот метод, который принимает int.

Это все, что нужно для этого. Если вы хотите, чтобы другие методы вызывались, либо приведите значение к (long), например, либо начните использовать значения, такие как 1.0 вместо 1.

Относительно вашего комментария: автоматизм включается только при необходимости. Но в вашем случае: A) вы используете int значение B) есть метод взятия int. Компилятор не превращает целые числа в длинные в двойники без причины!

0 голосов
/ 01 сентября 2018

Автоматическое преобразование происходит только тогда, когда метод принимает более широкий тип, чем ввод. Например, если вы удалите все функции void m1(..), кроме версии long. Затем вы можете передать целое число, и оно будет автоматически расширено до длинного.

В вашем примере есть метод, который принимает целое число, поэтому Java будет использовать этот метод, и расширение не происходит.

0 голосов
/ 01 сентября 2018

Литералы Int (например, 1) являются выражениями типа int.

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

  1. Если существует одна перегрузка, когда фактические параметры имеют те же типы, что и формальные параметры, вызовите это.
  2. Если существует единственная перегрузка без varargs, в которой фактические параметры могут быть автоматически преобразованы (например, путем расширения или un / boxing) в те же типы, что и формальные параметры, вызовите это.
  3. Если существует одна перегрузка varargs, при которой фактические параметры могут автоматически преобразовываться в типы тех же типов, что и формальные параметры, вызывающие это.
  4. В противном случае ошибка.

Эти фазы применяются по очереди, пока не будет найдено совпадение.

Поскольку имеется перегрузка m1, которая занимает int, на этапе 1 найдено совпадение, поэтому преобразование этого значения в другой тип не требуется.

...