Java - 使用WatchEvent抑制未选中的强制转换警告是安全的吗? [英] Java - Is it safe to suppress unchecked cast warning with WatchEvent?

查看:198
本文介绍了Java - 使用WatchEvent抑制未选中的强制转换警告是安全的吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下测试代码:

  FileSystem fs = FileSystems.getDefault 
路径conf = fs.getPath(。);
WatchKey key = null;
try {
WatchService watcher = fs.newWatchService();
conf.register(watcher,StandardWatchEventKinds.ENTRY_MODIFY);
while(true){
key = watcher.take(); // wait for
for(WatchEvent<?> event:key.pollEvents()){

WatchEvent.Kind<?& kind = event.kind();
if(StandardWatchEventKinds.OVERFLOW == kind)continue;

WatchEvent< Path> ev =(WatchEvent< Path>)事件;
路径文件= ev.context();
System.out.println(file);
}
}
} catch(IOException | InterruptedException e){
throw new RuntimeException(e.getMessage(),e);
}

编译器发出未选中的cast 与该行相关的警告

  WatchEvent< Path& ev =(WatchEvent< Path>)事件; code     

$ c> key.pollEvents()作为 WatchEvent<?> ,编译器不能知道在运行时它真的要去包含路径,而不是其他内容。



关于这一点,我想知道是否可以摆脱这个警告没有明确抑制它。我发现一些提示,虽然涉及到不同的情况,如,但在这里似乎他们可以控制通用列表的构建,而在我的情况下这是不可能的。



我还发现,他们建议禁止警告,同时检查如果实际类型是正确的(因为编译器不能自己做),但我不能设法在我的情况下做这些行。是否可以?



另一方面,在我的例子中,我得到这些 WatchEvent 注册一个路径对象的 WatchService c>:这个事实足以证明每个 WatchEvent<?> 从此 WatchService<?> 出来将有一个路径类型实现?如果这是真的,我可以安全地假设演员将永远是正确的,压制的警告?在这种情况下,有没有办法避免它而不抑制它?



非常感谢。





我可以立即检查明确指出:




返回事件的上下文。



在ENTRY_CREATE,ENTRY_DELETE和ENTRY_MODIFY事件的情况下,上下文是一个Path,它是注册到watch服务的目录之间的相对路径,创建,删除或修改。


在我的例子中,我正在观看 ENTRY_MODIFY events,因此我的 T 类型定义为 Path

  @ 

SuppressWarnings(unchecked)
WatchEvent< Path> ev =(WatchEvent< Path>)事件;

这是完全安全的,只能是< 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


I have the following test code:

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);
}

The compiler issues an unchecked cast warning related to the line

WatchEvent<Path> ev = (WatchEvent<Path>)event;

since event comes out of key.pollEvents() as a WatchEvent<?>, and the compiler can't tell if during runtime it's really going to contain a Path, and not something else.

Regarding this, I was wondering if it's possible to get rid of this warning without explicitly suppressing it. I found some hint, although related to quite different situations, like this, but here it seems that they can control how the generic list is built, while in my case this isn't possible.

I also found this, where they suggest to suppress the warning, checking at the same time if the actual type is the correct one (since the compiler can't do it on its own), but I couldn't manage to do something along these lines in my case. Is it possible? How would you do it?

On the other hand, in my case I'm getting these WatchEvent's from a WatchService registered with a Path object: is this fact alone enough to prove that every WatchEvent<?> coming out from this WatchService<?> will have a Path type implementation? If this is true, can I safely assume that the cast will always be correct and suppress the warning? Is there any way to avoid it without suppressing it in this case?

Thank you very much.

EDIT

I could have immediately checked the references that explicitly state that:

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.

So in my case I'm watching for ENTRY_MODIFY events, hence my T type is definetely a Path.

解决方案

I think the best option is to just suppress it

            @SuppressWarnings("unchecked")
            WatchEvent<Path> ev = (WatchEvent<Path>)event;

it's perfectly safe, it can only be <Path> and nothing else. The API designer went a little crazy of being too general.

WatchService is kind of difficult to use. I have the following utility class you might be intereted in

https://github.com/zhong-j-yu/bayou/blob/0.9/src/_bayou/_tmp/_FileMonitor.java

For example

_FileMonitor monitor = new _FileMonitor( ROOT_DIR );

List<Set<Path>> changes = monitor.pollFileChanges( TIMEOUT )
// return 3 sets, [0]=created, [1]=modified, [2]=deleted

这篇关于Java - 使用WatchEvent抑制未选中的强制转换警告是安全的吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆