简体   繁体   中英

Java - Is it safe to suppress unchecked cast warning with WatchEvent?

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM