отсутствующие или пропущенные циклы цикла в операторе android java switch - PullRequest
0 голосов
/ 06 ноября 2019

У меня есть бесконечный цикл while в качестве тестового примера для того, что я делаю и использую логику регистра переключателя, которая демонстрирует повторяющиеся и существенные отличия от логики if else. По сути, я перебираю, выбираю случайное число из набора {0,1,2} и затем жду 1000 мс, прежде чем выбрать другое число. Логика оператора if работает, как и ожидалось (т.е. печатает в журнал каждые 1000 мс с небольшим микросекундным дрейфом, который ожидается от не RTOS). С другой стороны, операторы switch, по-видимому, представляют собой то, что я бы описал как систему с максимальными усилиями (то есть время для каждой напечатанной строки кратно 1000 мс, но несколько итераций просто не печатаются). Другими словами, я вижу, что мой вывод журнала выводит что-то вроде

17: 50: 50: 00: 1

17: 50: 51: 00: 2

17: 50: 52: 01: 3

17: 50: 53: 01: 4

17: 50: 54: 02: 5

для логики if, ночто-то вроде

17: 50: 50: 00: 1

17: 50: 53: 01: 4

17: 50: 54: 02: 5

для логики переключения. Я также отметил несколько других деталей, которые могут иметь отношение к делу:

  • Здесь нет очевидного паттерна (т. Е. Нет пропущенного интервала каждые X временных шагов или что-то в этом роде).
  • Я добавил регистр по умолчанию, думая, что по какой-то причине я могу пропустить регистр, но это не тот случай (каламбур).

Есть ли для этого какая-либо очевидная причина? Предоставляет ли Java / Android больший приоритет коду операторов if и принимает пропущенные возвраты для операторов switch или чего-то подобного? Моя проблема решается просто с помощью операторов if вместо операторов switch, но мне просто интересно, почему это необходимо? Или я просто делаю некоторую опечатку простой ошибки в синтаксисе, которая вызывает это неожиданное поведение в операторах switch?

Это немного псевдокода, но он иллюстрирует единственные изменения, которые генерируют различия, которые я вижу (то есть, есть другой код в игре, но ничего не меняется, кроме этого). Ниже вы увидите корпус переключателя и, если еще, логику:

public void run(){
    while(true){
        action = randomIntBetweenZeroAndTwo()
        Log.i('actions', String.valueOf(action));
        switch (action){
            case 0:
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            case 1:
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            case 2:
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            default:
                Log.i("distribution", "default case selected with action = " + action);
                }
    }
}
public void run(){
    while(true){
        action = randomIntBetweenZeroAndTwo()
        Log.i('actions', String.valueOf(action));
        if (action == 0){
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        else if (action == 1){
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        else {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

Если есть какие-то различия, здесь приведены различные характеристики моей системы разработки:

ОС для ПК: Ubuntu 18.04

ОС Android: 5.1.1

Телефон: Nexus 4

Android Studio 3.5.2

Ответы [ 4 ]

3 голосов
/ 06 ноября 2019

С помощью переключателя вы должны указать, где дела должны «сломаться», иначе вы также попадете в другие дела.

switch (action){
        case 0:
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            break;
       ...
        default:
            Log.i("distribution", "default case selected with action = " + action);
            }

Без разрыва 0-кейс будет ограничен кейсом 1, кейс 2, вплоть до случая по умолчанию. Который МОЖЕТ быть тем, что вы хотите. Подумайте о программе, в которой вы хотите обрабатывать два случая одинаково. С оператором if вы бы сделали что-то вроде:

if (action == 0 || action == 1) {
   ...
}

В операторе switch это будет:

case 0:
    // prerhaps do some unique preprocessing (note: in this case this would differ from the above if-snippet)
    // because here is no break we will "fall through to 2"
case 1:
    ....
    break; // we will stop here and do NOT continue with case 2.

case 2:
    break;
2 голосов
/ 06 ноября 2019

Согласно моему пониманию, проблема возникает из-за того, что вы не ставите оператор break после каждого случая, поэтому просто введите break и попробуйте, как мой приведенный ниже код

public void run(){
    while(true){
        action = randomIntBetweenZeroAndTwo()
        Log.i('actions', String.valueOf(action));
        switch (action){
            case 0:
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                break;
            case 1:
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                break;
            case 2:
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                break;
            default:
                Log.i("distribution", "default case selected with action = " + action);
                }
    }
}
1 голос
/ 06 ноября 2019

Вы пропускаете break; в конце каждого case.

0 голосов
/ 06 ноября 2019

Глядя на свое заявление о переключении, вы, кажется, забыли разрывать каждый раз после проверки.

Попробуйте что-то вроде этого.

switch (action){
            case 0:
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                break;
            case 1:
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                break;
            case 2:
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                break;
            default:
                Log.i("distribution", "default case selected with action = " + action);
                }
...