#java
#java
Вопрос:
public static char determineGrade(float grade)
{
char letter;
if(grade>=90 amp;amp; grade<=100)
{
letter='A';
}
else if(grade>=80 amp;amp; grade<=89)
{
letter='B';
}
else if(grade>=70 amp;amp; grade<=79)
{
letter='C';
}
else if(grade>=60 amp;amp; grade<=79)
{
letter='D';
}
else if(grade<=59)
{
letter='F';
}
return letter;
}
Программа продолжает указывать мне инициализировать letter, но я не понимаю, зачем мне это нужно. Спасибо.
Комментарии:
1. Что произойдет, если
grade > 100
? Вы можете знать, что этого не может произойти, но компилятор этого не делает. Методы должны что-то возвращать, и здесь есть способ для метода что-то не возвращать.2. Компилятор не знает, что
100
это самый высокий класс. Просто инициализируйте, когда вы определяете переменную:char letter = '':
Ответ №1:
Почему я получаю ошибку при инициализации письма и как мне это исправить?
Проблема в том, что можно получить доступ к return
инструкции без присвоения значения letter
. (Это происходит, когда grade
значение больше 100.0. Хотя это может не иметь смысла в контексте вашего приложения, компилятор Java не может этого знать.)
Люди предложили вернуть значение «по умолчанию». Я думаю, что это неправильно, если только спецификация API не определяет значение по умолчанию. (И, ИМО, для этого нужен плохой дизайн API.)
Я думаю, что лучшим подходом является выдача исключения (например IllegalArgumentException
), если предоставленный аргумент не имеет смысла.
public static char determineGrade(float grade) {
if (grade >= 90 amp;amp; grade <= 100) {
return 'A';
} else if (grade >= 80 amp;amp; grade <= 89) {
return 'B';
} else if (grade >= 70 amp;amp; grade <= 79) {
return 'C';
} else if (grade >= 60 amp;amp; grade <= 79) {
return 'D';
} else if (grade >= 0 amp;amp; grade <= 59) {
return 'F';
} else {
throw new IllegalArgumentException("grade is out of range: " grade);
}
}
Другая проблема дизайна здесь заключается в том, уместно ли использовать числа с плавающей запятой для представления оценок. Существует риск того, что вычисление, которое вычисляет оценки, дает значения, которые немного «отклонены» из-за ошибки округления; т.е. 89.999998
вместо 90.0
. Если вы собираетесь использовать здесь тип с плавающей запятой, вам нужно использовать пороговые сравнения, а не простые >=
и <=
с целочисленным значением.
Комментарии:
1. ИМО, все исключительные случаи должны быть выброшены в начале метода.
2. @PhamTrung — Объявление непроверенных исключений необязательно.
Ответ №2:
Проблема в том :
else if(grade<=59)
{
letter='F';
}
Должно быть
else
{
letter='F';
}
Потому что у вас есть ряд условий if, поэтому компилятор не может знать, будет ли условие истинным во время выполнения. Итак, либо вам нужно объявить значение по умолчанию для letter
, либо у последнего else
не должно быть никаких условий.
Для оценки выше 100 должна быть какая-то проверка, чтобы справиться с этим.
если оценка выше 100 неприемлема, в начале метода должно быть создано исключение (как эмпирическое правило):
if(grade > 100){
throw new IllegalArgumentException("Invalid input"):
}
Комментарии:
1. Значит, превышение оценки
100
будетF
?2. @AstroCB Проблема компилятора в том, что ему нужно убедиться, что должно быть значение для
letter
. Логика не нужна, это проблема операционной системы3. Я понимаю проблему; Я просто указал на проблему с логикой вашего ответа в контексте вопроса. В более подходящем ответе также указывалось бы, что вам следует изменить первый оператор в
if/else
цепочке на readif(grade >= 90)
.4. @AstroCB ха-ха-ха, логика в том, что нет оценки выше 100, а если есть, то должно быть выдано исключение, вместо того, чтобы возвращать какое-либо значение.
5. @AstroCB хм, так это полностью зависит от проблемы операционной системы, верно ? 🙂
Ответ №3:
char letter
просто объявляет переменную типа char
. Инициализация означает присвоение ей начального значения, прежде чем переменная будет обработана в другом месте программы.
В вашем случае, if grade
не входит ни в один из диапазонов, которые вы явно проверяете, letter
требуется значение по умолчанию, которое может вернуть ваш метод. Поскольку это локальная переменная в вашем методе, компилятор не будет присваивать стандартное значение по умолчанию для char
, как указано в этом отрывке из документации:
Локальные переменные немного отличаются; компилятор никогда не присваивает значение по умолчанию неинициализированной локальной переменной. Если вы не можете инициализировать свою локальную переменную там, где она объявлена, обязательно присвоите ей значение, прежде чем пытаться ее использовать. Доступ к неинициализированной локальной переменной приведет к ошибке во время компиляции.
Вот почему вам нужно явно инициализировать его.
Ответ №4:
Попробуйте это,
public static char determineGrade(float grade) {
char letter = 0;
if (grade >= 90 amp;amp; grade <= 100) {
letter = 'A';
} else if (grade >= 80 amp;amp; grade <= 89) {
letter = 'B';
} else if (grade >= 70 amp;amp; grade <= 79) {
letter = 'C';
} else if (grade >= 60 amp;amp; grade <= 79) {
letter = 'D';
} else if (grade <= 59) {
letter = 'F';
}
return letter;
}
существует ситуация, когда все операторы if не выполняются (когда число> 100). Тогда переменная letter не имеет значения.Чтобы предотвратить это, переменная letter должна быть инициализирована значением по умолчанию.
Комментарии:
1. @AstroCB — о да, это так. Или, точнее, литерал
0
может быть присвоен achar
.2. @StephenC Интересно; я этого не знал.
3. Это происходит из-за области видимости ht vsriable, поскольку letter является локальной переменной (не атрибутом), компилятор не присваивает ей значение по умолчанию.
Ответ №5:
Поскольку char
задаются значения только в if
операторах, метод не знает, будет ли ему когда-либо присвоено значение (предполагается, что есть вероятность, что ни в одном из if
операторов не будет условия true), и поэтому вас просят указать начальное значение. Другим способом обойти это было бы превратить последний else if
оператор просто в else
, потому что он в любом случае охватывает все оставшиеся возможности if.