Submission: switch (...) instanceof feature

Jeroen van Maanen jeroen at lexau.org
Mon May 4 14:06:08 PDT 2009


Neal Gafter schreef:
> If we want a variable inside the switch statement with a different type 
> than outside, then the programmer should introduce a new variable.  That 
> allows the new form of the switch statement to be used with general 
> expressions instead of only a simply-named variable.  Something like this:

I disagree. The proposal was meant to deal with the case where a method gets an object of an unknown (or not completely known) type and where part of the method needs to perform specific actions based on the specific type. Currently, this situation needs a cast and a new name. I would like to do away with both of them, if possible. So I would like to see a scope where the same name is used for the same object but with a narrower type. Is can see the problems with getting the "switch" statement to accommodate this, so I'm happy very happy with the suggestion that an extension of the "if" statement would be more straight forward.

> switch instanceof (expression) {
>     case (String s):
>         // code for when the expression is of type String, using variable s
>     case (Integer i):
>         // etc
> }

I got lots of remarks about special cases of the switch statement that would be hard to handle. It would be hard to come up with a design that would behave similar to the old switch statement for integers, because the inheritance hierarchy prevents a jump table approach.

For readability, I persist in thinking that it is better to give the expression result a proper name and use that name throughout the method / class, than introducing a new name for each case:

Object var = expression;
if instanceof (String var) {
    // code for when the expression is of type String, using var
} else if instanceof (Integer var) {
    // etc.
}

> There would have to be either an implicit 'break' between the cases, or 
> the 'break' would be required.
> 
> Regards,
> Neal
> 
> On Mon, May 4, 2009 at 1:58 AM, Jeroen van Maanen <jeroen at lexau.org 
> <mailto:jeroen at lexau.org>> wrote:
> 
>     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 <mailto:Ulf.Zibis at gmx.de>>
>                 Sent: Apr 22, 2009 5:17 AM
>                 To: Derek Foster <vapor1 at teleport.com
>                 <mailto:vapor1 at teleport.com>>
>                 Cc: Gabriel Belingueres <belingueres at gmail.com
>                 <mailto:belingueres at gmail.com>>, Jeroen van Maanen
>                 <jeroen at entreact.com <mailto:jeroen at entreact.com>>,
>                 coin-dev at openjdk.java.net <mailto: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
>                 <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
>                         <mailto:belingueres at gmail.com>>
>                         Sent: Mar 30, 2009 7:31 AM
>                         To: Jeroen van Maanen <jeroen at entreact.com
>                         <mailto:jeroen at entreact.com>>
>                         Cc: coin-dev at openjdk.java.net
>                         <mailto: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