Ошибка типа возврата метода

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

 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 вместо случая переключения, но я все еще получаю тот же метод. Я подозревал, что это часть моей функции nextInt();, но не мог понять, что именно. Я был бы признателен за любое предложение о том, где я могу ошибаться.


person PizzaParrot    schedule 16.04.2018    source источник
comment
Что делать, если rCard = 20? (Компилятор не знает, что это невозможно) - что тогда возвращает ваш метод?   -  person John3136    schedule 17.04.2018
comment
Ничего общего с фактическим вопросом: я не занимаюсь Java, но не означает ли randomCard.nextInt (13), что случайное число имеет верхнюю границу 13 (12 + 1)? Результат 20 не должен быть возможен.   -  person Steve    schedule 17.04.2018
comment
@Steve компилятор этого не знает. в этом и смысл комментария   -  person OneCricketeer    schedule 17.04.2018
comment
Кроме того, это именно тот случай, когда требуется Map или даже просто массив строк.   -  person chrylis -cautiouslyoptimistic-    schedule 17.04.2018
comment
Не имеет отношения к первоначальной проблеме, но я хочу спросить, не должен ли Джек предшествовать Королеве? О, может быть, вы сначала подумали о женщинах :-P   -  person Michael Osofsky    schedule 17.04.2018
comment
Не совсем уверен, почему вы не используете предложения из своего предыдущего вопроса stackoverflow.com/questions/49714583/ или stackoverflow.com/questions/49591418/   -  person OneCricketeer    schedule 17.04.2018


Ответы (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;
}
person Michael Osofsky    schedule 16.04.2018
comment
Хотя мы с вами знаем, что он никогда не будет использоваться, компилятор недостаточно умен, чтобы понять это. - person Scott Hunter; 17.04.2018

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

Кроме того, несмотря на то, что простой 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;
}
person OneCricketeer    schedule 17.04.2018

Компилятор не может быть уверен, что одно из ваших 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));
}
person Elliott Frisch    schedule 17.04.2018
comment
Не по теме - считается ли использование статических блоков для инициализации постоянной карты хорошей практикой? - person OneCricketeer; 17.04.2018
comment
@cricket_007 Наличие глобальных переменных (вообще) обычно не считается лучшей практикой. Здесь я инициализирую поле private static. Следующим логическим местом для этого будет enum. - person Elliott Frisch; 17.04.2018

Этот код не может быть скомпилирован, потому что вы пропустили оператор возврата, если 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);
}
person Evgeny Kochergin    schedule 17.04.2018

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

 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());
}
person Evgeny Kochergin    schedule 17.04.2018