Почему приведенное выше, в частности (double) leftVal, (double) rightVal часть, является избыточностью?
приведенное выше приведение необходимо, чтобы вы явно указали, что вы хотите вызвать эту перегруженную функцию базового уровня. В противном случае код будет просто предполагать, что вы хотите выполнить рекурсию в том же методе. Итак, да, вы правы, говоря, что «первое приведение помогает компилятору определить, какую перегрузку выбрать»
Таким образом, второе приведение является неявным. Может быть, из-за того, что типы примитивны и легко преобразовываются?
Итак, если вы переходите от примитивного типа, требующего меньшего количества бит (int
- 32 бита), к примитивному типу, большее количество бит (double
- 64 бита), Java знает, что делать это во время выполнения. Однако, если вы go из double
(64 бит) в int
(32 бит), вам, как разработчику, необходимо явно выполнить приведение, так как вы можете столкнуться с потерей информации здесь . Вот почему при возврате необходимо приведение типа (int); вы переходите от double
к int
, который может быть с потерями.
Пример кода:
public class Test {
public int intMethod(int intArg) {
return intArg;
}
public long longMethod(long longArg) {
// will NOT compile, since we didn't explicitly cast to narrower int type (potentially lossy)
return intMethod(longArg);
}
}
public class Test {
public int intMethod(int intArg) {
return intArg;
}
public long longMethod(long longArg) {
// WILL compile, since we explicitly cast to narrower int type. Also note we do not need to cast result, since result is going from int --> long, which is not lossy
return intMethod((int) longArg);
}
}
public class Test {
public int intMethod(int intArg) {
// WILL compile. don't need to specify arg since its not lossy, but we do specify return type since its lossy
return (int) longMethod(intArg);
}
public long longMethod(long longArg) {
return 3L;
}
}
Я всегда думал, что Java очень строго относится к явному определению типов
Примитивы - это гораздо более тонкая функция языка Java. Я думаю, что по типам вы неявно ссылаетесь на Object
в Java. Вы правы, что Java намного строже в отношении приведения объектов. Если мы возьмем приведенный выше пример и будем использовать объекты Long
и Integer
, они не будут компилироваться и помечают предупреждение Cannot case java.lang.Long to java.lang.Integer
;
Примеры, которые не будут компилироваться из-за недействительности Приведение
public class Test {
public Integer intMethod(Integer intArg) {
return intArg;
}
public Long longMethod(Long longArg) {
return intMethod((Integer) longArg);
}
}
public class Test {
public Integer intMethod(Integer intArg) {
return longMethod((Long) intArg);
}
public Long longMethod(Long longArg) {
return 3L;
}
}
ps: стандартно ссылаться на все функции с тем же именем метода как перегруженные; не принято называть один метод "базовым" и говорить, что остальные перегружают этот метод