Erroneous JavaDoc for Path#register
David M. Lloyd
david.lloyd at redhat.com
Thu Dec 4 08:30:08 PST 2008
Actually, I'm wrong, identity comparison does *not* always work on enum
types because the JDK might make anonymous subtypes for enum constants that
override a method differently.
And the sad thing is, I've made the same mistaken assumption several times.
Will I ever learn? :-)
- DML
On 12/04/2008 10:14 AM, David M. Lloyd wrote:
> 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