Submission: switch (...) instanceof feature
Reinier Zwitserloot
reinier at zwitserloot.com
Mon May 4 02:51:00 PDT 2009
Why is this neccessary? We have a similar situation here as the
inherited exception issue: Rare and definitely broken (at runtime)
code will now break at compile time. This is technically 'backwards
incompatible', insofar that code that used to compile no longer does.
However, I believe the decision was made that this technical
incompatibility was acceptable, because the code made no runtime sense
in the first place. You have the same situation here:
old code:
Object x = foo();
if ( x instanceof String ) {
Integer y = (Integer)x;
}
would compile, eventhough it's clearly bogus. With this change:
if ( x instanceof String ) {
//within this block, 'x' is considered to be both a String and
whatever x's actual type is, if it's not a strict supertype of String.
}
the original clearly broken code would all of a sudden produce a
compile error, because casting a String to an Integer is not allowed
(at compile-time too, not just at runtime). You could make a rule to
relax this restriction (and generate a warning instead). Personally
I'd say that clearly broken code should generate compile-time
exceptions, that's why we went with static typing in the first place,
so there's no need to complicate the JLS with such a relaxation just
to be backwards compatible. That's kind of like Windows Vista taking
the trouble to be compatible with viruses written for XP, just so they
can say "we're 100% compatible!". (That's a hypothetical, not a
comment on Microsoft's programming division. I don't even use windows,
I have no idea if Vista works like that).
Why would we possibly want to introduce new syntax here?
--Reinier Zwitserloot
Like it? Tip it!
http://tipit.to
On May 4, 2009, at 10:58, Jeroen van Maanen 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>
>>>> 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