Запрос относительно оператора равенства (совместимые операнды) в JAVA

Я новичок в JAVA и проходил через оператор равенства. Попробовав несколько комбинаций операндов, я немного запутался в том, что именно является определением совместимых операндов для оператора равенства (==) в Java.

int x = 23;
if (x == 23.3f) {   // compiler accepts it. (may be because both are primitives)

int x = 23;     
Double d = new Double(23.3); 
if (x == d) {    // compiler accepts it. (may be compatible pair of primitive and object reference)

int x = 23;
String s = "hello";
if (x == s)   // compiler throws error  - incompatible operands for == operator.

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

3 ответа

Решение
  1. Компилятор принимает это, потому что x а также 23.3f имеют примитивные числовые типы. И сравнение вернется false,

  2. Компилятор принимает это, потому что Java распаковывает Double Возражать double примитивно при сравнении.

  3. Компилятор не может принять это, потому что x является примитивным числовым типом, и s это ссылка на String экземпляр класса. Невозможно сравнить примитивный номер и ссылку на объект.

За

int x = 23;
if (x == 23.3f) 

Если вы посмотрите на байт-код с помощью javap -v, int будет преобразован в float, т.е. i2f будет вызван, а затем они будут сравниваться как 2 значения с плавающей запятой, используя fcmpl,

public static void main(java.lang.String[]);
  Code:
   Stack=2, Locals=2, Args_size=1
   0:   bipush  23
   2:   istore_1
   3:   iload_1
   4:   i2f       // The line of interest. Converts int to float.
   5:   ldc     #16; //float 23.3f
   7:   fcmpl     // compare two floats
   8:   ifne    11
   11:  return

В третьем случае вы сравниваете примитив с объектом (строкой), что невозможно.

Строки - это объекты. == сравнивает объекты по ссылке, а не по их внутреннему значению. Все другие(int, double) сравниваются в == там ссылки на объекты, поэтому в случае строки она не совпадает, поэтому для строки мы должны .equals оператор также Java чувствителен к регистру, поэтому при сравнении строки вы должны позаботиться о Case's of strings

Оператор равенства налагает некоторые ограничения и преобразования, они довольно большие и описаны в спецификации языка https://docs.oracle.com/javase/specs/jls/se11/html/jls-15.html

  1. Таким образом, в первом случае "x" переводится в тип с плавающей запятой перед сравнением.
  2. Во втором "d" распаковывается, а "x" повышается до двойного типа перед сравнением.
  3. В третьем случае во время компиляции возникает ошибка, поскольку String нельзя распаковывать для сравнения с примитивным типом.

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

Другие вопросы по тегам