Почему два перечисления несовместимы с оператором ==? - PullRequest
0 голосов
/ 27 октября 2018

У меня вопрос: я не знаю, не могу сравнить два разных перечисления с оператором ==.Это мой код:

public class EnumExercises {

enum Seasons{
    SPRING, WINTER;

    Seasons() {
        System.out.println("Hello");
    }
}

enum TestResult {
    PASS, FAIL, SPRING; 
}
public static void main(String[] args) {
    Seasons s = Seasons.WINTER;
    Seasons s2 = Seasons.SPRING;
    TestResult t = TestResult.PASS;
    System.out.println(s2==t);  //incompatible...why?
    System.out.println(s2.equals(t));


}}

Большое спасибо.

Ответы [ 2 ]

0 голосов
/ 27 октября 2018

Enum.Equals () сравнивает два перечисления для эквивалентности как по типу, так и по значению. Таким образом, законно использовать его на двух разных типах Enum. Оператор ==, с другой стороны, сравнивает числовое значение двух перечислений и предполагает , что они относятся к одному типу. Ваш первый тест не пройден, потому что Seasons и TestResult не одного типа. Последнее успешно, потому что они оба основаны на типе Enum - они просто не эквивалентны. Вы можете обойти это, если вам действительно нужно двумя разными методами.

Однако заранее я посоветую вам использовать их с осторожностью, поскольку в дальнейшем они могут вызвать всевозможные проблемы. Перечисления бывают разных типов, предположительно по причине. Отстранение от этой причины - проблема, которая порождает вопрос «Почему?». Если у вас есть законный ответ на этот вопрос, то, возможно, вам стоит обратить внимание на рефакторинг кода, чтобы сделать его ненужным .

Теперь, чтобы как-нибудь избежать неприятностей с их сравнением, я пообещал два метода. Первый по значению. Приведите оба перечисления к целым и сравните их по значению, например ((int) s2) == ((int) t) ;. По сути, это то же самое, что и использование оператора ==, за исключением того, что вы удалили тип из сравнения. Второй по смыслу - сравните само перечисление путем преобразования их обоих в строку, поэтому s2.ToString (). Equals (t.ToString ()) ;. При этом «ВЕСНА» будет сравниваться с «ПРОЙДЕНО», поэтому числовая эквивалентность больше не будет проблемой.

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

0 голосов
/ 27 октября 2018

По той же причине, по которой вы не можете сказать

String s = "1";
int t = 1;

if (s == t) {

s2 и t бывают разных типов. Они не сопоставимы.

В фоновом режиме типы enum компилируют свои имена, так что это не будет делать то, что вы хотите, если не приведёт к совместимым типам. Если вы хотите сделать это, вы должны использовать name() или toString(). Смотрите, например этот ответ .

if (s2.name().equals(t.name())) {

Как правило, == на объектах проверяет, ссылаются ли они на одну и ту же память. Это не то, что вы хотите проверить здесь. Похоже, вы ищете поведение примитивов (равное, если значения равны), которое вы не получите от таких сравнений объектов.

...