#java
#java
Вопрос:
package com.csl.bps.util;
import java.awt.Event;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.HashMap;
import javax.servlet.ServletContextEvent;
public class Reloader implements Runnable{
private boolean firstLoad = true;
private ServletContextEvent eventCopy = null;
private File configFile = null;
private String configFilePath = null;
private HashMap map = null;
private BufferedReader reader = null;
private long lastModifiedTime = 0;
public Reloader(ServletContextEvent event) {
eventCopy = event;
//event.getServletContext().setAttribute("i", new Integer(2));
}
public void run() {
configFilePath = (String)eventCopy.getServletContext().getInitParameter("billRunDetailConfig");
if(configFilePath == null)
{
eventCopy.getServletContext().log("Warning: No bill run detail config file found. Please check the file and restart.");
}
configFile = new File(configFilePath);
if(firstLoad == true)
{
map = createMap(configFile);
lastModifiedTime = configFile.lastModified();
eventCopy.getServletContext().setAttribute("BunRunDetail", map);
eventCopy.getServletContext().log("nnFirst load of bill run detail config file. HashMap loaded.n");
firstLoad = false;
}
else
{
eventCopy.getServletContext().log("nnAnother load of bill run detail config file. Checking for the file's last modified time...n");
if(configFile.lastModified() != lastModifiedTime)
{
map = createMap(configFile);
lastModifiedTime = configFile.lastModified();
eventCopy.getServletContext().setAttribute("BunRunDetail", map);
eventCopy.getServletContext().log("Config file changed. HashMap is hashed again.");
}else
{
eventCopy.getServletContext().log("Config file is not changed.");
}
}
}
private HashMap createMap(File configFile){
HashMap map = null;
try{
reader = new BufferedReader(new FileReader(configFile));
}catch(FileNotFoundException ex){
ex.printStackTrace();
}
return map;
}
}
Я хотел бы создать любое исключение для вызывающего любого метода, но я не могу, например:
Я могу это сделать:
private HashMap createMap(File configFile) throws FileNotFoundException{
HashMap map = null;
try{
reader = new BufferedReader(new FileReader(configFile));
}catch(FileNotFoundException ex){
//ex.printStackTrace();
throw ex;
}
return map;
}
Но в приведенном выше:
if(firstLoad == true)
{
map = createMap(configFile);
lastModifiedTime = configFile.lastModified();
eventCopy.getServletContext().setAttribute("BunRunDetail", map);
eventCopy.getServletContext().log("nnFirst load of bill run detail config file. HashMap loaded.n");
firstLoad = false;
}
Здесь, в строке map = createMap(configFile)
я получил ошибку запроса в eclipse для не обработанного исключения, но я могу только добавить к нему предложение try catch.
Я бы хотел, чтобы он выдавал исключение своему вызывающему объекту и позволял вызывающему объекту обрабатывать исключение, потому что, если я вернусь сюда, я не уверен, что все ресурсы закрыты.
Почему его подпись не содержит предложения throws? Предполагается ли, что он не создаст никакого исключения?
Если появится исключение, и я оберну его предложением try / catch, остановится ли поток и уведомит ли он родительский?
Ответ №1:
Причина, по которой вы не можете добавить предложение «throws» к методу run(), заключается в том, что run() определен в интерфейсе Runnable, и его подпись не содержит предложения throws.
Комментарии:
1. Я знаю это, но почему его подпись не содержит предложения throws? Предполагается ли, что он не создаст никакого исключения?
2. Runnable — это очень универсальный интерфейс; любые проверенные исключения, которые он может выдавать, слишком многочисленны, чтобы перечислять (поскольку вы можете поместить в него что угодно), поэтому он просто не перечисляет ни одного и ожидает, что run () обработает проверенные исключения и, возможно, выдаст непроверенные исключения и ошибки.
Ответ №2:
Вы не должны добавлять какие-либо проверенные исключения в объявление. Причина просто в том, что интерфейс, который можно запустить, не объявляя исключение, обещает, что оно не будет выдано никаким Runnable.
Я бы хотел, чтобы он выдавал исключение своему вызывающему объекту и позволял вызывающему объекту обрабатывать исключение, потому что, если я вернусь сюда, я не уверен, что все ресурсы закрыты.
Вам нужно перехватить исключение, но вместо этого вы можете создать другое непроверенное исключение.
try {
...
} catch (FileNotFoundException e) {
throw new MyRuntimeFileNotFoundException(e);
}
Таким образом, вы рискуете забыть перехватить его позже (поскольку он не объявлен). Но иногда это необходимо. Конечно, вы можете использовать simply throw new RuntimeException(e)
вместо своего собственного.
Комментарии:
1. 1 за то, что он (намного, намного) более точный. хотя у меня все еще есть сомнения по поводу необходимости перехвата исключения из
run
в большинстве случаев.2. @MByD согласен, в большинстве случаев вам это не нужно. Однажды мне пришлось обернуть один Runnable в другой и перехватить исключение, чтобы я мог зарегистрировать его и выполнить некоторую очистку. Возможно, это можно было бы сделать по-другому.
3. Я не понимаю…… Если я не могу добавить к нему объявление throw, как я могу его создать? И если я не могу его создать, есть ли у нас способ сообщить вызывающему «произошло что-то неправильное»?
4. Ого, я могу обернуть исключение в исключение во время выполнения? Это намного удобнее.
5. Действительно, это называется переносом исключений или цепочкой .
Ответ №3:
Когда вы переопределяете метод, реализуете метод интерфейса или реализуете абстрактный метод, вы переопределяете его методом с точной сигнатурой, которая включает в себя имя, типы параметров и порядок, броски (РЕДАКТИРОВАТЬ, как указано maaartinus, это относится только к проверяемым исключениям) (если существует) и возвращаемый тип. Если вы хотите реализовать Runnable, вы должны реализовать метод run
Runnable
интерфейса. Сигнатура этого метода не содержит никаких throw
, поэтому вы не переопределяете его своим методом.
Более того, хотя вы можете объявить два метода с одинаковым именем, но с разными аргументами, такими как:
public int foo(int i);
и
public int foo(String s);
Вы не можете объявить два метода с одинаковым именем и параметрами, которые отличаются только тем, что они выдают (РЕДАКТИРОВАТЬ, как указано maaartinus, это относится только к проверяемым исключениям) или что они возвращают. например, вы не можете объявить два из трех методов одновременно:
public int foo();
public boolean foo();
public boolean foo() throws FileNotFoundException;
public boolean foo() вызывает исключение FileNotFoundException;
Поскольку вы реализуете, Runnable
вы должны реализовать public void run()
, и вы не можете реализовать public void run() throws FileNotFoundException
.
Комментарии:
1. На самом деле, вы совершенно не правы. При реализации
Closeable
вы можете реализовать либоvoid close() throws IOException
, либо простоvoid close()
. Дажеvoid close() throws NullPointerException
это нормально. Вы просто не должны добавлять никаких проверенных исключений, вот и все.