Ошибка типа возвращаемого значения метода

Я использую метод раздачи карт в моей программе Black Jack. Это мой метод:

 public static String dealCard() {
    Random randomCard = new Random();
    int min = 1;
    int rCard = min + randomCard.nextInt(13);
    switch(rCard) {
    case 1 : return "2"; 
    case 2 : return "3";
    case 3 : return "4";
    case 4 : return "5";
    case 5 : return "6";
    case 6 : return "7";
    case 7 : return "8";
    case 8 : return "9";
    case 9 : return "10";
    case 10 : return "Queen";
    case 11 : return "Jack";
    case 12 : return "King";
    case 13 : return "Ace";
    }
 }

Однако я получаю следующую ошибку ...

This method must return a result of type String.

Вот почему я запутался, потому что разве я не возвращаю строку, когда выбираю футляр, а затем он возвращает карточку? Я в полном замешательстве. Я попытался переключить свой метод и попытаться сделать это с помощью операторов If вместо switch case, но я все еще получаю тот же метод. Я подозревал, что это часть моей функции nextInt();, но я не мог понять, что именно. Буду признателен за любое предложение о том, где я могу ошибиться.

Что если rCard = 20? (Компилятор не знает, что это невозможно) - что тогда возвращает ваш метод?

John3136 17.04.2018 01:54

Ничего общего с фактическим вопросом: я не занимаюсь Java, но не randomCard.nextInt (13) означает, что верхняя граница случайного числа равна 13 (12 + 1)? Результат 20 не может быть возможным.

Steve 17.04.2018 02:00

@Steve компилятор этого не знает. В этом суть комментария

OneCricketeer 17.04.2018 02:04

Кроме того, это именно тот случай, когда требуется Map или даже просто массив строк.

chrylis -cautiouslyoptimistic- 17.04.2018 02:04

Не имеет отношения к исходной проблеме, но я хочу спросить, не должен ли Джек предстать перед Королевой? Ой, может быть, вы думали "сначала дамы" :-P

Michael Osofsky 17.04.2018 02:06

Не совсем уверен, почему вы не используете предложения из своего предыдущего вопроса stackoverflow.com/questions/49714583/… или stackoverflow.com/questions/49591418/…

OneCricketeer 17.04.2018 02:07
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
6
798
5

Ответы 5

Добавьте default: в свою выписку switch:

public static String dealCard() {
    Random randomCard = new Random();
    int min = 1;
    int rCard = min + randomCard.nextInt(12);
    String cardDealt = "";
    switch (rCard) {
        case 1:
            cardDealt = "Ace";
            break;
        case 2:case 3:case 4:case 5:case 6:case 7:case 8:case 9:
            cardDealt = Integer.toString(rCard);
            break;
        case 10:
            cardDealt = "Jack";
            break;
        case 11:
            cardDealt = "Queen";
            break;
        case 12:
            cardDealt = "King";
            break;
        default:
            throw new IllegalArgumentException("rCard unexpectedly out of range");
    }
    return cardDealt;
}

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

Scott Hunter 17.04.2018 02:03

Вам все равно нужно возвращать значения за пределами возможных случаев.

Кроме того, хотя простой if-else будет выглядеть чище, вы можете использовать оператор провала case

switch(rCard) {
    case 10 : return "Queen";
    case 11 : return "Jack";
    case 12 : return "King";
    case 13 : return "Ace";
    case 1 :
    case 2 :
    case 3 : 
    case 4 : 
    case 5 : 
    case 6 : 
    case 7 : 
    case 8 : 
    case 9 : return String.valueOf(rCard + 1);
    default: return null;
}

Компилятор не может быть уверен, что один из ваших операторов case будет выполнен, и поэтому вы получите значение return. должен - возвращаемое значение. Вы можете добавить к default футляр switch. Или просто переместите свой последний return в последний оператор. Кроме того, повторная инициализация Random при каждом вызове - плохая идея. В цикле вы мощь получаете то же семя.

private static Random randomCard = new Random();
private static final int MIN = 1; // <-- this is a CONSTANT
private static final int MAX = 13; // <-- this is a CONSTANT
public static String dealCard() {
    int rCard = MIN + randomCard.nextInt(MAX);
    switch(rCard) {
    case 1 : return "2"; 
    case 2 : return "3";
    case 3 : return "4";
    case 4 : return "5";
    case 5 : return "6";
    case 6 : return "7";
    case 7 : return "8";
    case 8 : return "9";
    case 9 : return "10";
    case 10 : return "Queen";
    case 11 : return "Jack";
    case 12 : return "King";
    }
    return "Ace";
}

Вы мог оптимизируете его немного дальше (imo) с помощью Map и getOrDefault, например

private static Random randomCard = new Random();
private static final int MIN = 1; // <-- this is a CONSTANT
private static final int MAX = 13; // <-- this is a CONSTANT
private static final Map<Integer, String> faceCards = new HashMap<>();
static {
    faceCards.put(11, "Jack");
    faceCards.put(10, "Queen");
    faceCards.put(12, "King");
    faceCards.put(13, "Ace");
}

public static String dealCard() {
    int rCard = MIN + randomCard.nextInt(MAX);
    return faceCards.getOrDefault(rCard, String.valueOf(rCard + 1));
}

Не по теме - считается ли использование статических блоков для инициализации постоянной карты хорошей практикой?

OneCricketeer 17.04.2018 02:09

@ cricket_007 Использование глобальных переменных (вообще) не считается лучшей практикой. Здесь я инициализирую поле private static. Следующим логичным местом для этого был бы enum.

Elliott Frisch 17.04.2018 02:11

Этот код не может быть скомпилирован, потому что вы пропустили оператор возврата, если rCard будет меньше 1 или больше 13. У вас есть 2 варианта решения этой проблемы:

  • добавить параметр по умолчанию в переключатель
  • бросить IllegalStateException в конце метода

Итак, окончательный код должен выглядеть так:

public static String dealCard() {
    Random randomCard = new Random();
    int min = 1;
    int rCard = min + randomCard.nextInt(13);
    switch(rCard) {
        case 1 : return "2";
        case 2 : return "3";
        case 3 : return "4";
        case 4 : return "5";
        case 5 : return "6";
        case 6 : return "7";
        case 7 : return "8";
        case 8 : return "9";
        case 9 : return "10";
        case 10 : return "Queen";
        case 11 : return "Jack";
        case 12 : return "King";
        case 13 : return "Ace";
    }
    throw new IllegalStateException("No return value fo case " + rCard);
}

Более элегантный и оптимизированный способ использования перечислений:

 public enum Card {
    TWO(2, "2"),
    THREE(3, "3"),
    FOUR(4, "4"),
    FIVE(5, "5"),
    SIX(6, "6"),
    SEVEN(7, "7"),
    EIGHT(8, "8"),
    NINE(9, "9"),
    TEN(10, "10"),
    QUEEN(11, "Queen"),
    JACK(12, "Jack"),
    KING(13, "King"),
    ACE(14, "Ace");

    private final int value;
    private final String name;

    private static final Card[] VALUES = values();
    private static final int SIZE = VALUES.length;
    private static final Random RANDOM = new Random();

    Card(int value, String name) {
        this.value = value;
        this.name = name;
    }

    public static Card getRandomCard() {
        return VALUES[RANDOM.nextInt(SIZE)];
    }

    public int getValue() {
        return value;
    }

    public String getName() {
        return name;
    }
}

public static void main(String[] args) {
    System.out.println(Card.getRandomCard().getName());
}

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