0

I need find the average grade of all the students in the university and create custom exception while finding the average in the Arrays.asList. Exception should be thrown if int warCraftGrade< 0 or int warCraftGrade> 10. I have the following code:

public class Student {
String name;
public final int warCraftGrade;

public Student(String name, int warCraftGrade) {
    this.name = name;
    this.warCraftGrade = warCraftGrade;
}
public String getName() {
    return name;
}
public int getWarCraftGrade() {
    return warCraftGrade;
}

I have the list of students:

static List<Student> students = Arrays.asList(
    new Student("Geoffrey Baratheon", 8),
    new Student("Barristan Selmy", 6) //and so on
);

And the method of getting the average:

double warCraftAverageGrade = students.stream()
                .mapToDouble(Student::getWarCraftGrade)
                .average()
                .getAsDouble();

I created special exception class:

public class GradeException extends Exception{
public GradeException() {
}
public GradeException(String message) {
    super(message);
}
public GradeException(String message, Throwable cause) {
    super(message, cause);
}

And the class to define the exception method:

public class StudentActions {
public static void range (Student student) throws GradeException {
    if (student.warCraftGrade < 0 || student.warCraftGrade > 10) {
        throw new GradeException("Wrong grade");
    }
}

} The problem occurs when I'm trying to use StudentActions.range() method:

public static void main(String[] args) {
    try {
        StudentActions.range();
        double warCraftAverageGrade = students.stream()
                .mapToDouble(Student::getWarCraftGrade)
                .average()
                .getAsDouble();
        System.out.println("Average grade in WarCraft for the entire university = " + warCraftAverageGrade);
    } catch (GradeException e) {
        System.out.println("Grade is out of range (0-10)");
    }

What is the correct solution to form the custom exception in such a case? The correct code must throw GradeException if the grade, for example, is negative:

//new Student("Jorah Mormont", -8)

Thank you in advance!

Shubt
  • 17
  • 6

1 Answers1

0

It would be better to move the exception into the constructor instead of having to catch an exception every time you get the average. Simply make it so that you cannot construct an invalid object. And in your particular case, it does not make sense to throw a checked exception (an exception that does not extend a RuntimeException and is appended to the throws clause, forcing the caller to deal with it).

This answer suggests when it is appropriate to use checked exceptions (emphasis mine):

I also think that throwing checked exceptions can be OK1, assuming that the checked exception is 1) declared, 2) specific to the problem you are reporting, and 3) it is reasonable to expect the caller to deal with a checked exception for this2.

2 - For example, the existing FileInputStream constructors will throw FileNotFoundException if you try to open a file that does not exist. Assuming that it is reasonable for FileNotFoundException to be a checked exception3, then the constructor is the most appropriate place for that exception to be thrown. If we threw the FileNotFoundException the first time that (say) a read or write call was made, that is liable to make application logic more complicated.


Also, I would recommend moving the actual grade range logic into a method, rather than forcing the caller to do it every time.

One last thing: I'd make your methods nonstatic since you're dealing with an instance. In Java (I don't know what language you're coming from), this, the current instance, is available in all nonstatic methods and is favored over passing an instance into a static method.


Take a look at these questions:

Vadim Hagedorn
  • 159
  • 1
  • 12
  • Thank you for recommendations! I followed your advice by moving the exception into the constructor and it works. The only negative moment of using this approach is that the further code execution stops when an exception is thrown even if I catch it. Java is my first language and I started learning it month ago. – Shubt May 23 '21 at 17:27
  • That's the whole point of an exception... It stops code execution in order to handle an error – Vadim Hagedorn May 24 '21 at 00:53