Java - 使用 WatchEvent 抑制未经检查的投射警告是否安全?
Java - Is it safe to suppress unchecked cast warning with 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
作为 WatchEvent<?>
从 key.pollEvents()
出来,编译器无法判断在运行时它是否真的包含 Path
,并且不是别的。
关于这一点,我想知道是否有可能在不显式抑制它的情况下摆脱这个警告。我发现了一些提示,虽然与完全不同的情况有关,比如 this,但在这里他们似乎可以控制通用列表的构建方式,而在我的情况下这是不可能的。
我还发现 ,他们建议取消警告,同时检查实际类型是否正确(因为编译器无法自行完成),但是在我的案例中,我无法按照这些思路做一些事情。可能吗?你会怎么做?
另一方面,在我的例子中,我从使用 Path
对象注册的 WatchService
中获取这些 WatchEvent
:这个事实是否足以证明从这个 WatchService<?>
出来的每个 WatchEvent<?>
都会有一个 Path
类型的实现?如果这是真的,我可以安全地假设演员表总是正确的并取消警告吗?在这种情况下,有什么办法可以避免它而不抑制它吗?
非常感谢。
编辑
我本可以立即检查 the references 明确指出:
T context()
Returns the context for the event.
In the case of ENTRY_CREATE, ENTRY_DELETE, and ENTRY_MODIFY events the context is a Path that is the relative path between the directory registered with the watch service, and the entry that is created, deleted, or modified.
所以在我的例子中,我正在监视 ENTRY_MODIFY
事件,因此我的 T
类型肯定是 Path
.
我认为最好的选择就是压制它
@SuppressWarnings("unchecked")
WatchEvent<Path> ev = (WatchEvent<Path>)event;
万无一失,只能是<Path>
,别的都不行。 API 设计师因为过于笼统而有点疯狂。
WatchService
有点难用。我有以下实用程序 class 你可能会感兴趣
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
我有以下测试代码:
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
作为 WatchEvent<?>
从 key.pollEvents()
出来,编译器无法判断在运行时它是否真的包含 Path
,并且不是别的。
关于这一点,我想知道是否有可能在不显式抑制它的情况下摆脱这个警告。我发现了一些提示,虽然与完全不同的情况有关,比如 this,但在这里他们似乎可以控制通用列表的构建方式,而在我的情况下这是不可能的。
我还发现
另一方面,在我的例子中,我从使用 Path
对象注册的 WatchService
中获取这些 WatchEvent
:这个事实是否足以证明从这个 WatchService<?>
出来的每个 WatchEvent<?>
都会有一个 Path
类型的实现?如果这是真的,我可以安全地假设演员表总是正确的并取消警告吗?在这种情况下,有什么办法可以避免它而不抑制它吗?
非常感谢。
编辑
我本可以立即检查 the references 明确指出:
T context()
Returns the context for the event.
In the case of ENTRY_CREATE, ENTRY_DELETE, and ENTRY_MODIFY events the context is a Path that is the relative path between the directory registered with the watch service, and the entry that is created, deleted, or modified.
所以在我的例子中,我正在监视 ENTRY_MODIFY
事件,因此我的 T
类型肯定是 Path
.
我认为最好的选择就是压制它
@SuppressWarnings("unchecked")
WatchEvent<Path> ev = (WatchEvent<Path>)event;
万无一失,只能是<Path>
,别的都不行。 API 设计师因为过于笼统而有点疯狂。
WatchService
有点难用。我有以下实用程序 class 你可能会感兴趣
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