Java - Безопасно ли подавлять непроверенное предупреждение о приведении с помощью WatchEvent?
У меня есть следующий тестовый код:
FileSystem fs = FileSystems.getDefault();
Path conf = fs.getPath(".");
WatchKey key = null;
try {
WatchService watcher = fs.newWatchService();
conf.register(watcher, StandardWatchEventKinds.ENTRY_MODIFY);
while(true) {
key = watcher.take(); // waits
for (WatchEvent<?> event : key.pollEvents()) {
WatchEvent.Kind<?> kind = event.kind();
if (StandardWatchEventKinds.OVERFLOW == kind) continue;
WatchEvent<Path> ev = (WatchEvent<Path>)event;
Path file = ev.context();
System.out.println(file);
}
}
} catch (IOException | InterruptedException e) {
throw new RuntimeException(e.getMessage(), e);
}
Компилятор выдает unchecked cast
предупреждение, относящееся к линии
WatchEvent<Path> ev = (WatchEvent<Path>)event;
поскольку event
выходит из key.pollEvents()
как WatchEvent<?>
и компилятор не может сказать, если во время выполнения он действительно будет содержать Path
и не что-то еще.
В связи с этим мне было интересно, возможно ли избавиться от этого предупреждения, не подавляя его явно. Я обнаружил некоторую подсказку, хотя и связанную с совершенно разными ситуациями, например, вот так, но здесь кажется, что они могут контролировать построение общего списка, в то время как в моем случае это невозможно.
Я также нашел это, где они предлагают подавить предупреждение, одновременно проверяя, является ли фактический тип правильным (поскольку компилятор не может сделать это самостоятельно), но мне не удалось сделать что-то вместе эти строки в моем случае. Является ли это возможным? Как бы вы это сделали?
С другой стороны, в моем случае я получаю эти WatchEvent
это из WatchService
зарегистрирован с Path
объект: достаточно ли одного этого факта, чтобы доказать, что каждый WatchEvent<?>
выходит из этого WatchService<?>
будет иметь Path
реализация типа? Если это правда, могу ли я с уверенностью предположить, что приведение будет всегда правильным и подавить предупреждение? Есть ли способ избежать этого, не подавляя его в этом случае?
Большое спасибо.
РЕДАКТИРОВАТЬ
Я мог бы сразу же проверить ссылки, которые явно заявляют, что:
T context()
Возвращает контекст для события.
В случае событий ENTRY_CREATE, ENTRY_DELETE и ENTRY_MODIFY контекст представляет собой путь, который представляет собой относительный путь между каталогом, зарегистрированным в службе наблюдения, и записью, которая создана, удалена или изменена.
Так что в моем случае я слежу за ENTRY_MODIFY
события, следовательно, мой T
тип определенно Path
,
1 ответ
Я думаю, что лучший вариант - просто подавить это.
@SuppressWarnings("unchecked")
WatchEvent<Path> ev = (WatchEvent<Path>)event;
это совершенно безопасно, это может быть только <Path>
и ничего больше. Дизайнер API сошел с ума от того, что слишком общий.
WatchService
довольно сложно использовать. У меня есть следующий служебный класс, в котором вы можете быть заинтересованы
https://github.com/zhong-j-yu/bayou/blob/0.9/src/_bayou/_tmp/_FileMonitor.java
Например
_FileMonitor monitor = new _FileMonitor( ROOT_DIR );
List<Set<Path>> changes = monitor.pollFileChanges( TIMEOUT )
// return 3 sets, [0]=created, [1]=modified, [2]=deleted