Erroneous JavaDoc for Path#register

David M. Lloyd david.lloyd at redhat.com
Thu Dec 4 08:14:47 PST 2008


I didn't know about the <?> thing with generic varargs.  I've always just 
avoided it.

Yeah, I see what you're saying about set creation.  But I think the common 
usage would be more like:

register(myWatcher, EnumSet.of(ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY), 
emptySet());

(some implied static imports there)

Yeah, a new set creation method would be helpful for the heterogeneous enum 
type case - maybe something like one of the following:

    // use type to locate the right nested enum set - identity comparison 
on the Class works because of the
    // nature of enums
    Set<Enum> aggregate(EnumSet<? extends Enum> one, EnumSet<? extends 
Enum> two);
    Set<Enum> aggregate(EnumSet<? extends Enum> one, EnumSet<? extends 
Enum> two, EnumSet<? extends Enum> three);
    // ..how many sets before it becomes slower than HashSet?  maybe zero. :-)

    // Surely doing a simple linear if/else scan of one to perhaps five 
arguments will be faster than building a
    // whole hashset?  One notes that Collections.singletonSet() already 
accommodates the first case
    Set<T> set(T one);
    Set<T> set(T one, T two);
    Set<T> set(T one, T two, T three);
    Set<T> set(T one, T two, T three, T four);
    Set<T> set(T one, T two, T three, T four, T five);

Though I guess I'm going off in a different direction now... :-)

- DML

On 12/04/2008 09:45 AM, Matthias Ernst wrote:
> [moved from my duplicate thread]
> 
> When you have good Set creation methods, i.e. EnumSet, then that would
> be a good option IMHO. Or nio could offer these if java.util doesn't
> get it done. Arrays should go away.
> 
> new HashSet<Type>(Arrays.asList(a, b, c)) is however not an option.
> 
> Regarding the generic array problem: if I'm not mistaken, you're safe
> with <?> . It is trivially always typesafe and the compiler shouldn't
> warn.
> 
> Matthias
> 
> 
> On Thu, Dec 4, 2008 at 4:23 PM, David M. Lloyd <david.lloyd at redhat.com> wrote:
>> On 12/04/2008 02:45 AM, Matthias Ernst wrote:
>>>
>>> http://openjdk.java.net/projects/nio/javadoc/java/nio/file/Path.html#register(java.nio.file.WatchService,%20java.nio.file.WatchEvent.Kind[],%20java.nio.file.WatchEvent.Modifier...)
>>>
>>> Barring any language changes I missed, the example code does not
>>> compile. It requires an explicit array creation, not?
>>>
>>> WatchKey key = dir.register(watcher, new WatchEvent.Kind<?>[] {
>>>  ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY
>>> });
>>>
>>>
>>> Given that there are no modifiers defined as of today and I would
>>> expect them to be empty most of the time (that's why they're called
>>> modifiers), wouldn't it be nicer if the two parameters were switched?
>> Unfortunately, if you have a varargs method parameter which is of a generic
>> type, you'll generally get an annoying compile-time warning stating that
>> you're implicitly creating an array of generic type.  On the other hand, the
>> second parameter actually is an *explicit* generic array creation, so...?
>>
>> Perhaps it would be better if both of these parameters were Set<> types like
>> this:
>>
>> public abstract WatchKey register(WatchService watcher,
>>                                  Set<WatchEvent.Kind<?>> events,
>>                                  Set<WatchEvent.Modifier> modifiers)
>>                           throws IOException;
>>
>> This way, one could take advantage of EnumSet by creating enums to implement
>> each interface for a particular provider.  E.g. the standard events class
>> "StandardWatchEventKind" could become:
>>
>> /** Typed in an email client, forgive egregious errors */
>> public class StandardWatchEventKind {
>>    enum PathKind implements WatchEvent.Kind<Path> {
>>        // I have no idea if these are the proper names.  Just for
>> illustration...
>>        ENTRY_CREATE("create", Path.class),
>>        ENTRY_DELETE("delete", Path.class),
>>        ENTRY_MODIFY("modify", Path.class),
>>        ;
>>        private final String name;
>>        private PathKind(String name) {
>>            this.name = name;
>>        }
>>
>>        public String getName() {
>>            return name;
>>        }
>>
>>        public Class<Path> getType() {
>>            return Path.class;
>>        }
>>    }
>>
>>    enum VoidKind implements WatchEvent.Kind<Void> {
>>        OVERFLOW("overflow"),
>>        ;
>>        private final String name;
>>        private VoidKind(String name) {
>>            this.name = name;
>>        }
>>
>>        public String getName() {
>>            return name;
>>        }
>>
>>        public Class<Void> getType() {
>>            return Void.class;
>>        }
>>    }
>>
>>    // Not strictly necessary but maybe desirable?
>>    public static PathKind ENTRY_CREATE = PathKind.ENTRY_CREATE;
>>    ...
>> }
>>
>> Then one could use EnumSets for watch event kind sets that are all of a type
>> (which seems like it would be a common situation, no?), and a plain HashSet
>> otherwise.
>>
>> - DML
>>



More information about the nio-dev mailing list