Submission: switch (...) instanceof feature
Gabriel Belingueres
belingueres at gmail.com
Mon Mar 30 07:31:11 PDT 2009
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.
Third:
} catch (Exception exception) {
switch (exception.getCause()) instanceof {
case ParseException:
log.warn("Could not get status for '" + id + ": " +
exception.getCause());
default:
log.warn("Could not get status for '" + id + ", exception);
}
}
in the case you intentionally left out the break statement, then the
switch statement is not any clearer than doing an if.
in the case that you wanted the break statement on the ParseException
case, it is even clearer to use two catch blocks (one for
ParseException and other for Throwable.
2009/3/29 Jeroen van Maanen <jeroen at entreact.com>:
> I'd like to coin a switch (...) instanceof statement as a new feature of the
> Java language. Please accept the attached proposal for review.
>
> Regards, Jeroen
>
> PROJECT COIN SMALL LANGUAGE CHANGE PROPOSAL FORM v1.0
>
> AUTHOR(S): Jeroen van Maanen <http://lexau.org/contact.html>
>
> OVERVIEW
>
> FEATURE SUMMARY: The instanceof switch statement allows for clear and
> concise
> handling of alternatives that depend on the type of a given object.
>
> MAJOR ADVANTAGE: The instanceof switch statement removes the need for
> different
> names for the same object with different types and the extra declarations
> and
> casts to define those names.
>
> MAJOR BENEFIT: Why is the platform better if the proposal is adopted?
>
> MAJOR DISADVANTAGE: Coders, reviewers, and IDE's need to be able to read the
> new statement and interpret and treat it correclty.
>
> ALTERNATIVES: There are no alternatives.
>
> EXAMPLES
>
> SIMPLE EXAMPLE:
>
> 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() + ">");
> }
> }
>
> ADVANCED EXAMPLE:
>
> public StatusEnum getStatus(String id) {
> StatusEnum result;
> try {
> result = internalGetStatus(id);
> } catch (Exception exception) {
> switch (exception.getCause()) instanceof {
> case ParseException:
> log.warn("Could not get status for '" + id + ": " +
> exception.getCause());
> default:
> log.warn("Could not get status for '" + id + ", exception);
> }
> }
> }
>
> public class PrettyPrinter {
> private Writer writer;
>
> public PrettyPrinter(Writer writer) {
> this.writer = writer;
> }
>
> public write(Object object) {
> switch (object) instanceof {
> case String:
> writer.write(stringDenotation(object));
> case Collection:
> writer.write(object.getClass().getSimpleName() + ": [");
> for (Object element : object) {
> write(element);
> writer.write(",");
> }
> writer.write("]");
> case Map:
> write(object.entrySet());
> case Map.Entry:
> write(object.getKey());
> writer.write(":");
> write(object.getValue());
> case void:
> writer.write("null");
> default:
> // TODO: deal with arrays of unknown base type
> writer.write("<" + object.toString() + ">");
> }
> }
>
> private stringDenotation(String str) {
> ...
> }
>
> }
>
> DETAILS
>
> SPECIFICATION: The switch instanceof feature adds an alternative to the
> switch
> statement to the grammar.
>
> SwitchStatement:
> switch ( Expression ) SwitchBlock
> switch ( Identifier ) instanceof TypeSwitchBlock
>
> TypeSwitchBlock:
> { TypeSwitchBlockStatementGroups? TypeSwitchLabels? }
>
> TypeSwitchBlockStatementGroups:
> TypeSwitchBlockStatementGroup
> TypeSwitchBlockStatementGroups TypeSwitchBlockStatementGroup
>
> TypeSwitchBlockStatementGroup:
> TypeSwitchLabel BlockStatements
>
> TypeSwitchLabel:
> case Type :
> case void :
> default :
>
> COMPILATION: The statement
>
> switch (<<identifier>>) instanceof {
> case <<type1>>:
> <<statements1 using identifier>>
> case <<type2>>:
> <<statements2>>
> ...
> case void:
> <<statementsVoid>>
> ...
> default:
> <<statementsDefault>>
> }
>
> Would be compiled by desugaring it to
>
> if (<<identifier>> instanceof <<type1>>) {
> <<type1>> <<identifier + "$1">> = (<<type1>>) <<identifier>>;
> <<statements1 with identifier replaced by identifier$1>>
> }
> else if (<<identifier>> instanceof <<type2>>) {
> <<type2>> <<identifier + "$2">> = (<<type2>>) <<identifier>>;
> <<statements2 with identifier replaced by identifier + "$2">>
> }
> ...
> else if (<<identifier>> == null) {
> <<statementsVoid>>
> }
> ...
> else {
> <<statementsDefault>>
> }
>
> TESTING: The feature can be tested by compiling and running the examples and
> comparing the results with the had coded expected desugared versions.
>
> LIBRARY SUPPORT: The feature needs no additional library support.
>
> REFLECTIVE APIS: The feature does not affect reflective api's.
>
> OTHER CHANGES: The feature does not need other changes.
>
> MIGRATION: This feature does not invalidate existing code. An existing code
> base could be scanned for type casts. Occurrences of type casts should be
> manually evaluated and, if desired, recoded using the new feature.
>
> COMPATIBILITY
>
> BREAKING CHANGES: This feature does not invalidate existing code.
>
> EXISTING PROGRAMS: This feature has no impact on existing code.
>
> REFERENCES
>
> EXISTING BUGS: There are no existing Sun bug ids related to this proposal.
>
> URL FOR PROTOTYPE: Not available.
>
>
>
>
More information about the coin-dev
mailing list