When a method can throw a checked exception but does not catch it, you must declare that in the method signature using throws:
public static String readFile(String path) throws IOException {
FileReader reader = new FileReader(path);
int ch = reader.read();
reader.close();
return String.valueOf((char) ch);
}
The throws IOException part tells callers that this method might throw an IOException. Any code calling readFile() must either wrap the call in a try-catch or declare throws IOException on its own method signature.
This creates a chain. The exception propagates up the call stack until some method catches it. If no method catches it, the program terminates.