Submission: switch (...) instanceof feature

Jeroen van Maanen jeroen at lexau.org
Mon May 4 01:58:56 PDT 2009


A colleague of mine pointed out that "if (... instanceof ...)" is currently syntactically correct code. Suddenly the "if" statement would show kind of a meta side effect for a highly specific subset of tests. He suggested that the new "type narrowing if" would get a clearly distinguished syntax, for example:

a concise syntax similar to the extended "for" statement:

  if (name : Type) { ... }

or verbose:

  if instanceof (name : Type) { ... }

or like a declaration rather that a test, which clearly emphasizes the side effect:

  if instanceof (Type name) { ... }

Jeroen

Jeroen van Maanen schreef:
> I agree that "if (... instanceof ...)" is more readable than the 
> extension of "switch" that I proposed originally. I believe that this 
> feature that avoids an unnecessary new name and cast would be of great 
> benefit to the Java language.
> 
> Jeroen
> 
> Derek Foster schreef:
>> I notice that the example you gave is actually an argument for an "if" 
>> that respects instanceOf, rather than a 'switch' that does. It seems 
>> to me like an abuse of notation to use a 'switch' in a case like this 
>> where only one decision (it is or it isn't a subtype of a given type) 
>> is being made.
>>
>> Although I am skeptical of the 'switch instanceof' feature, for the 
>> reasons I outlined below, I would very much like to see Java implement 
>> the 'if instanceof' feature that is implied in the proposal, and which 
>> various people have been suggesting, so that this very common coding 
>> pattern:
>>
>> if (foo instanceof Bar) {
>>      Bar bar = (Bar)foo;
>>      doSomethingWith(bar);
>> }
>>
>> could be simplified to:
>>
>> if (foo instanceof Bar) {
>>      doSomethingWith(foo);
>> }
>>
>> with no loss of type safety. It seems to me that your example would be 
>> more readable with such a construct than it is with the 'switch 
>> instanceof' feature.
>>
>> I had intended to submit a proposal along these lines myself, but 
>> simply ran out of time to put it together. Still, it seems to me that 
>> there's been widespread agreement on the list that the 'if instanceof' 
>> sub-proposal is a good idea.
>>
>> Derek
>>
>>
>>
>>
>>
>> -----Original Message-----
>>> From: Ulf Zibis <Ulf.Zibis at gmx.de>
>>> Sent: Apr 22, 2009 5:17 AM
>>> To: Derek Foster <vapor1 at teleport.com>
>>> Cc: Gabriel Belingueres <belingueres at gmail.com>, Jeroen van Maanen 
>>> <jeroen at entreact.com>, coin-dev at openjdk.java.net
>>> Subject: Re: Submission: switch (...) instanceof feature
>>>
>>> Am 22.04.2009 06:55, Derek Foster schrieb:
>>>> Like Gabriel, I have severe reservations about this proposal. I am 
>>>> concerned that it will encourage people to avoid the common OOP 
>>>> "best practice" of using virtual method dispatch in favor of doing 
>>>> an explicit "switch" on each subtype of a type, in cases where doing 
>>>> so is not necessary.
>>>>
>>>> I concede that there are a few (FEW!) places where doing the 
>>>> equivalent of a switch on instances of a type is necessary (for 
>>>> instance, if the type is in a library you don't have the ability to 
>>>> change). I can see some value in this proposal for that purpose. 
>>>> However, I would very much not like to see use of this construct 
>>>> become commonplace. I already see too many instances of people doing 
>>>> the equivalent of "if (object.type == FOO) {doThis(); } else if 
>>>> (object.type == BAR) { doThat(); }" instead of writing 
>>>> "object.doSomething();"
>>>>
>>>>   
>>> I like to provide an example where
>>>
>>> "object.doSomething();"
>>>
>>>  doesn't work:
>>>
>>>    synchronized Charset lookup(String lowCanonical) {
>>>        // cache is initialized with available Charset classes names
>>>        Object o = cache.get(lowCanonical);
>>>        // Check cache first
>>>        if (o instanceof String) {
>>>            // Instantiate new charset
>>>            Charset cs = newCharset((String)o, lowCanonical);
>>>            // Cache it
>>>            if (cs != null)
>>>                cache.put(lowCanonical, cs);
>>>            return cs;
>>>        }
>>>        return (Charset)o;
>>>    }
>>>
>>>
>>>  This would look much nicer, as it avoids casting:
>>>
>>>    synchronized Charset lookup(String lowCanonical) {
>>>        // cache is initialized with available Charset classes names
>>>        switch (Object o = cache.get(lowCanonical) instanceof ?) {
>>>            case String :
>>>                // Instantiate new charset
>>>                Charset cs = newCharset(o, lowCanonical);
>>>                // Cache it
>>>                if (cs != null)
>>>                    cache.put(lowCanonical, cs);
>>>                return cs;
>>>            case Charset :
>>>                return o;
>>>        }
>>>    }
>>>
>>>
>>> Refer:
>>> https://java-nio-charset-enhanced.dev.java.net/source/browse/java-nio-charset-enhanced/tags/milestone4/src/sun/nio/cs/FastCharsetProvider.java?rev=684&view=markup 
>>>
>>> http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6790402
>>> http://mail.openjdk.java.net/pipermail/coin-dev/2009-March/001182.html
>>> http://mail.openjdk.java.net/pipermail/coin-dev/2009-April/001328.html
>>>
>>> - My example could also be smartly coded without switch..case 
>>> statement, if we would enhance if statement accordingly
>>> - I also would like to have possibility to declare variables in if 
>>> clause, like it's possible in for clause:
>>>
>>>        if ((Object o = cache.get(lowCanonical)) instanceof String)
>>>            ... ;
>>>        else if (o instanceof Charset)
>>>            ... ;
>>>
>>> -Ulf
>>>
>>>
>>>> Derek
>>>>
>>>> -----Original Message-----
>>>>  
>>>>> From: Gabriel Belingueres <belingueres at gmail.com>
>>>>> Sent: Mar 30, 2009 7:31 AM
>>>>> To: Jeroen van Maanen <jeroen at entreact.com>
>>>>> Cc: coin-dev at openjdk.java.net
>>>>> Subject: Re: Submission: switch (...) instanceof feature
>>>>>
>>>>> IMO I'm against this.
>>>>>
>>>>> First, it is against current best practices for the design of
>>>>> object-oriented software to make easier to code something with a case
>>>>> statement on types/classes.
>>>>>
>>>>> Second:
>>>>> void log(Object object) {
>>>>>   switch (object) instanceof {
>>>>>   case String:
>>>>>     logger.debug("'" + object + "'");
>>>>>   case Date:
>>>>>     logger.debug(object.getTime());
>>>>>   case void:
>>>>>     logger.debug("null");
>>>>>   default:
>>>>>     logger.debug("<" + object.toString() + ">");
>>>>>   }
>>>>> }
>>>>>
>>>>> It think it is clearer (when possible) writing it with several
>>>>> overloaded methods and double dispatching.
>>>>>
>>>>> ....
>>>>>     
>>


More information about the coin-dev mailing list