2013-08-04 1 views
2

Моего перечислимого объявления:Android/Java: методы Enum разбивая приложение

public enum Note { A, A_SHARP, B, C, C_SHARP, D, D_SHARP, 
    E, F, F_SHARP, G, G_SHARP; 

    public String toString(Note note) { 
     if (note == Note.A) 
      return "A"; 
     else if (note == Note.A_SHARP) 
      return "A#"; 
     else if (note == Note.B) 
      return "B"; 
     else if (note == Note.C) 
      return "C"; 
     else if (note == Note.C_SHARP) 
      return "C#"; 
     else if (note == Note.D) 
      return "D"; 
     else if (note == Note.D_SHARP) 
      return "D#"; 
     else if (note == Note.E) 
      return "E"; 
     else if (note == Note.F) 
      return "F"; 
     else if (note == Note.F_SHARP) 
      return "F#"; 
     else if (note == Note.G) 
      return "G"; 
     else if (note == Note.G_SHARP) 
      return "G#"; 
     else 
      return ""; 
    } 

    public Note getNext() { 
     int index = ordinal(); 
     index++; 
     if (index > values().length) 
      return values()[0]; 
     else 
      return values()[index]; 
    } 
} 

Всякий раз, когда я называю любого из этих двух методов, мое приложение падает. Здесь я назову их:

public void ChangeSound(View v) { 
    note = note.getNext(); 
    tvSounds.setText(note.toString(note)); 
} 

ChangeSound() - это метод onClick для кнопки. Если я удаляю обе строки в ChangeSound(), код работает так, как должен, но если одна из двух строк находится там, приложение вылетает при нажатии кнопки. Любые идеи почему? Заранее спасибо!!

EDIT ** нота является переменной типа Примечание

Спасибо всем! Он возвращал нуль (см. Ответы Джейсона С (мой комментарий)). Все это было полезно для меня!

+1

Что вы подразумеваете под «сбоями»? Есть ли конкретное исключение? –

+0

Один из нижеприведенных ответов ниже - это не ответ, но это хорошее предложение; используйте переключатель для toString. – DwB

+0

Поскольку вы говорите, что note.toString (примечание) также вызывает проблему, более вероятно, что «примечание» равно null. Убедитесь, что это не так, и подумайте о том, как статизировать Note.toString (Note), чтобы он мог обрабатывать нули. См. Мой ответ ниже. –

ответ

0

Неясно, что вы имеете в виду под «аварии», и вы также не показываете достаточного контекста (что такое «примечание»?), но наиболее вероятная причина основана на том факте, что вы заявили, что один из этих двух сбоев линии, кажется, что «примечание» равно null. Если «note» имеет значение null, то ChangeSound выдаст исключение NullPointerException. Вы должны убедиться, что если ChangeSound предполагает, что «note» не является нулевым, это на самом деле.

Также вы должны сделать toString (обратите внимание) статический метод и определить нестатический переопределение toString(). Это даст Note.toString (Примечание) способность правильно обрабатывать аннулирует:

public static String toString (Note n) { 
    return n == null ? "" : n.toString(); 
} 

Edit: Как указано в других ответах, вы должны использовать> = вместо> (даже == будет достаточно), то есть также потенциальная проблема.

+0

Вы правы, он возвращал null. Я поставил инициализацию переменной в неправильном месте (ошибка новобранец). Я очень разочарован в себе, ха-ха. – hardyboy16jm

4

Вы должны использовать >= так, вероятно, вы получаете некоторые OutOfBoundsException

if (index >= values().length) 
     return values()[0]; 
    else 
     return values()[index]; 
} 

Кроме того, вместо переключателя вы можете STH так:

public enum Note { A("A"), A_SHARP("A#"), B("B"); 

private String s; 
public Note (String s) { 
    this.s = s; 
} 
public String toString() { 
    return s; 
} 
+0

На самом деле,> = не нужно. Поскольку «index» является результатом ординала(), он не будет превышать значений(). Length - 1. –

+2

index ++ после этого будет причиной этой проблемы. – Tala

+0

Хороший улов, извините. –

2

Изменить это:

if (index > values().length) 

к этому:

if (index >= values().length) 
+1

Собственно, это необходимо. Прочтите код еще раз. – splungebob

+0

Да, это так. Извини за это. –

+0

Спасибо, это также поставило бы проблему – hardyboy16jm

0

Этот вопрос уже был замечен другими ответами. Однако следует отметить, что вы могли бы упростить код двумя способами:

  • , связывая строковое представление нот с константами перечислений непосредственно
  • с помощью модуля вместо вашей, если/еще в getNext

Это может выглядеть следующим образом:

public enum Note { A("A"), A_SHARP("A#"), B("B"), C("C"), C_SHARP("C#"), D("D"), 
     D_SHARP("D#"), E("E"), F("F"), F_SHARP("F#"), G("G"), G_SHARP("G#"); 

    private final String noteName; 
    Note(String noteName) { 
     this.noteName = noteName; 
    } 

    @Override 
    public String toString() { 
     return noteName; 
    } 

    public Note getNext() { 
     int nextIndex = (ordinal() + 1) % values().length; 
     return values()[nextIndex]; 
    } 
} 

И в основной код:

note = note.getNext(); 
tvSounds.setText(note.toString()); 
+0

Статический toString (примечание) отлично справился бы с этим, придерживаясь предполагаемого интерфейса OP. Модуль является элегантным, но не необходимым в этой ситуации, ординал() + 1 будет максимальным значением.length(). –

+0

@JasonC (a) 'toString (Примечание)' кажется ненужным (вам нужен экземпляр заметки в обоих случаях, поэтому имеет смысл вызывать 'note.toString()', чем 'Note.toString (note)' (b) 'G_SHARP.ordinal() + 1' равно' values.length() ', поэтому' values ​​() [G_SHARP.ordinal() + 1] 'будет генерировать исключение. – assylias

+0

(a) Согласовано полностью повторно: не нужно - * except *, что у OP было одно, поэтому я предполагаю, что он этого хочет. Статическая версия может обрабатывать значения null. (b) Я предлагал «if (nextIndex == values.length()) nextIndex = 0» вместо модуля Я не предлагал полностью отказаться от проверки. :-) –

Смежные вопросы