Win a copy of Rust Web Development this week in the Other Languages forum!

Kishori Sharan

Author
+ Follow
since Oct 16, 2014
Cows and Likes
Cows
Total received
15
In last 30 days
0
Total given
0
Likes
Total received
10
Received in last 30 days
0
Total given
0
Given in last 30 days
0
Forums and Threads
Scavenger Hunt
expand Ranch Hand Scavenger Hunt
expand Greenhorn Scavenger Hunt

Recent posts by Kishori Sharan

Congratulations Salvin Francis, Serge Yurk, Campbell Ritchie, and Robert Ingmarsson!
2 years ago
I would like to thank Java Ranch for giving me this opportunity to promote my book "Java 13 Revealed". And, my big THANK YOU to all who participated in this promotion by giving me an opportunity to answer their questions!
2 years ago

Is the new switch some sort of syntactic sugar, then? But syntactic sugar can be a very good thing  Make the code the programmer sees simpler and you reduce the effort to program it, and the risk of errors.



Yes.

Does it list the possible reasons for the changes in Java 13?


Yes.


2 years ago
Thanks Kevin. My favorite topics in Java 13 are
1. Text blocks
2. Enhanced switch
2 years ago
They are preparing for a big new feature called pattern-matching. Enhancing old switch is a tiny part of the pattern-matching feature, which is still in proposal phase. Of course, new switch expressions and new switch without fall-through will help developers write concise and less error-prone code.
2 years ago
The unqualified use of yield in already compiled code works in JDK 13. That is, if you have used an yield() as a method call compiled in JDK8, the same compiled code can be used (I mean, it can be run using JDK13 runtime) in JDK13 without forcing you to make any changes. You will need to make changes only if you try to re-compile your existing source code using JDK13.  
2 years ago
Hello Jorge,
In my opinion, we all will start using the new switch syntax. All new Java developers will also need to learn the old switch syntax for maintaining the old applications that were written in last 25 years using the old switch. switch is one of the basic component of the Java programming language and I expect all developers to be very proficient in using both syntax. Once you have new switch available as a standard feature, your team will need to make a coding convention to use the new switch whenever possible.
2 years ago
Hello Jorge,
Yes. My book compares the old and new switch syntax. The book explains switch in the following order:
1. It explains how to do things using old switch.
2. It explains changes to the old switch and how to do the same things better using the old switch.
3. It explains how to do the same things using new switch in a concise and less error-prone ways.


There is no performance gain in using the new switch syntax. To the Java runtime, there is no new switch. All your code using new switch syntax is converted to old switch syntax by the compiler. Using new switch, you get new features such as switch expressions and less error-prone code.



2 years ago
Hello Henry,
My main sources of information are JEPs and various mailing lists for JDK development. For example, I keep vising https://openjdk.java.net/projects/jdk/14/ for JEPs for JDK14. Writing a book to be released soon after the JDK is released is a bit messy because specifics of new features are not written in stone until the new JDK version becomes a release candidate. I start writing when a new feature is announced to be part of the new JDK. I keep revising the material and run the examples regularly to see any breaking changes. I tell my publisher to hold the technical review for the book until the new version of the JDK is in the release candidate phase, so the technical reviewer can catch any last minute changes. And finally, after all the hassles, you guys get to see the book!
2 years ago
Here are the highlights of changes to switch:
  • It was added in Java 12 as a preview feature.
  • It stayed as a preview feature in Java 13 with a minor change – the break with value in a switch expression in Java 12 was replaced with a yield statement in Java 13.
  • switch has received new syntax. The new switch syntax allows you to use an arrow (->) instead of a colon (:) to separate the case label from its corresponding code. In my book, I call them as switch-with-colon and switch-with-arrow.
  • Now you can also use multiple constants in one case label.
  • You can use both switch-with-colon and switch-with-arrow as a statement and an expression. Before this change, you had only switch-with-colon and you could use it only as a statement.
  • To support enhancements to switch, there is a new yield statement, which can be used in a switch expression. This may break your existing code, which would be easy to fix though. More details on this in a separate section below.

  • Let me give you an example of all changes with a little explanation. Some people do not know what a preview feature is, so I will start with explaining it first.

    What Is a Preview Feature?
    A preview feature of the Java SE Platform is a fully specified and fully implemented language or virtual machine feature, which is available in a JDK feature release, but is not a permanent feature of the JDK yet. A preview feature is provided to solicit developers feedback. Developers are expected to experiment with the features in real world use-cases. Based on the feedback, a preview feature may become permanent (standard feature) in a future release with or without modifications or it may be removed altogether. A preview feature is not meant to be used in production. Refer to JEP 12 at https://openjdk.java.net/jeps/12 for more details on preview features.

    A preview feature is not backward compatible. You cannot run class files that contain preview features from Java 12 using Java 13 runtime.
    Since a preview feature is not meant to be used in production, it is not enabled in the compiler and runtime by default. You must use the --enable-preview option with the compiler and runtime to use a preview feature.  You will need to use the --release or -source option when you use the --enable-preview option to compile the source code. To compile source code with preview features in JDK 13, you would use:

    If you do not use the --enable-preview option to compile the source code with preview features, you receive compile-time errors similar to the following:

    If you enable preview features at compile-time, the compiler prints notes suggesting you to compile with a -Xlint:preview option, so you can see the warnings.
    To run compiled classes with preview features, you specify the --enable-preview option with the java command:

    If you want to use JShell to explore preview features, you need to start it with the --enable-preview option:
    Enhancements to Traditional Switch
    Java has always been backward compatible. Adding breaking changes to the traditional switch was not an option to the language designers. The preview feature provides you new ways of using the traditional switch without breaking your old code. Here are the changes to the traditional switch:
  • You can have multiple constants in a case label.
  • You can use switch as an expression.

  • Previously, you had to use one case label per constant. The new switch syntax allows you to use a comma-separated list of constants in a case label. The following snippet of code uses the traditional switch with multiple constants in a case label to match a letter against a vowel and consonant:


    With the new switch syntax, you have collapsed five case labels into one. You still need to use a break statement because the traditional switch statement still uses default fall-through semantics.
    The preview feature allows you to use the traditional switch as an expression. An expression evaluates to a value (or yields a value). Now you can write code like:

    Notice the use of a semicolon at the end of the switch expression. The switch expression is part of the variable declaration for the str variable, so the entire variable declaration must end with a semicolon. Think of the previous variable declaration as shown:

    The traditional switch allowed you to use only statements for a switch label. The preview feature has introduced a new yield statement. Its syntax is:

    yield expression;

    The yield statement evaluates its expression and transfers control to the enclosing switch expression. The value of the expression becomes the value of the switch expression.

    Tip The yield statement can only be used inside a switch expression. You cannot use the break statement inside a switch expression.

    Here is an example of a switch expression using the traditional switch:

    This is a simple example where each switch label contains only one yield statement. You can have multiple statements in a switch label. However, each switch label must contain one yield statement that will represent the value of the switch expression. Typically, you will not print something from an expression. Let us do it just for the demonstration purpose to show that you can have multiple statements in a switch label for a switch expression. The following snippet of code prints a message when "case 1:" is executed:

    Recall that you cannot use the break statement inside a switch expression. The yield statement completes a switch expression. In this statement, when count is 1, a message is printed, and the yield statement completes the switch expression by yielding "One" and other case labels below "case 1:" are not executed.
    Here is a challenge for you. Let me switch the two statements in the previous snippet of code as follows. Now, the yield statement is first and the System.out.println() is second. Will the following snippet of code compile?

    If your answer is no, you are correct. The yield statement completes the switch expression making the System.out.println() statement unreachable. Java does not allow unreachable statements. This snippet of code generates the following compile-time error:



    New Switch Syntax
    The new switch retains most of the syntax from the traditional switch, except the character to separate a switch label from its code. It uses an arrow (->) instead of a colon (:). The traditional "case label:" becomes "case label->". This is the only syntactic difference you have for the new switch. There are several semantic differences that I explain in this section.
    Often, I need to distinguish which switch I am talking about–the new one or the old new. I refer to the old switch as traditional switch, switch-with-colon, or switch with "case label:". I refer to the new one as new switch, switch-with-arrow, or switch with "case label->". Java Language Specification refers to the switch block associated with the traditional switch as switch labeled statement groups and the switch block associated with the new switch as switch labeled rules. Whichever name you use to refer to the new switch, here is its syntax:

    The syntax allows for one or more constants in a case label. The code associated with a switch label is restricted to one of the following: an expression, a block statement, and a throw statement. I will explain the rationale behind this rule shortly.
    Let us look at the rules used to process the new switch followed with examples of each rule:
  • The default is no fall-through in the new switch. This means, you no longer need to use a break statement to stop executing the switch labels following the matched switch label.
  • Only one "thing" can be executed as part of a matched switch label. That "thing" can be an expression, a block statement, or a throwstatement. In traditional switch, a group of statements was allowed causing the scoping issue where the entire switch block was executed in one scope. Using these constraints, if you have more than one statement to execute, you are forced to use a block statement that will have a new scope for the switch label. This allows you to have the same functionality as the traditional switch, but code is less error-prone.
  • The new switch can be used as a statement or as an expression.

  • The following snippet of code rewrites the previous example, which used the traditional switch statement, using the new switch statement:

    Notice the use of the System.out.println() in each switch label. Didn't I say that each switch label can have an expression, a block statement, or a throw statement?  I did say that. In Java, a method call (in this case, System.out.println()) is an expression. When you add a semicolon after the method call, it becomes an expression statement. Here are the detailed rules about using an expression in a switch label with arrow:
  • In a switch statement, the expression must be an expression statement–an expression, which can be converted to a statement by adding a semicolon to it.
  • In a switch expression, the expression may be any valid Java expression.

  • The following snippet of code rewrites the previous example using a switch expression:
     

    This time, "One", "Two", etc. are expressions. You cannot convert them to expression statements by adding a semicolon. When the switch expression (count) matches one of the case labels, the corresponding expression ("One", "Two", etc.) becomes the value for the switch expression.
    If you have to compute the value in a switch label using some logic, you will need to use the yield statement to return the value as the value for the switch expression. Consider the following snippet of code that uses a switch expression to compute a value:

    The case label uses a simple expression "Vowel" when the character is a vowel. The default label uses a block statement to use logic to determine whether it is a consonant or not a letter. Note the use of the yield statements inside the if and else blocks. The default label does not use very complex logic. You can replace it with an expression as shown:

    Consider the following snippet of code that uses the new switch statement:

    The code uses one case label and one default label. Both contain more than one statement, so you are forced to use a block statement ({}) in each label. Notice that you have used the same variable name upperChar inside the code for both labels. Declaring duplicate variables in a switch block like this was also possible with traditional switch, but you had to remember to use a block statement, whereas the new switch forces you to use a block statement.

    Does New switch Replace the Old One?
    Once the new switch becomes a standard feature in Java SE (maybe in Java SE 14), you are encouraged to use it in place of the traditional switch when it fits your needs. However, it is not a complete replacement for the traditional switch statement. Remember that the traditional switch offers fall-through by default and you have a way (using the break statement) to override the default behavior. Consider the following trivial example that uses the fall-through feature of the traditional switch statement:

    If the value of count is 1, it prints "One Two Three"; for 2, it prints "Two Three"; for 3, it prints "Three"; and, for any other values, it prints "Over-My-Head". Implementing this logic is simple because of the fall-through feature of the traditional switch statement. There is no straightforward way to implement this logic using the new switch syntax because the new switch does not provide the fall-through feature. You got the point–use the new syntax whenever possible and use the traditional switch when fall-through is needed.
    I was curious to get a bit more insight into the new switch features and how the compiler handles them. So, I tried to decompile all my examples, which were written using new switch syntax. You can use http://www.javadecompilers.com to decompile your Java code. When I decompiled my code, I did not see any new switch syntax. I found out that in all cases, the code using new switch syntax was translated to the traditional switch. Even though the new switch uses the old switch behind the scene, as a developer you gain a lot of benefits using the new syntax. You get compact and less error-prone code, and a new big feature, which is using switch as an expression!

    A Switch Expression is a Poly Expression
    A poly expression in Java is an expression whose type depends on the context. Therefore, the same poly expression can take on different types in different contexts. A switch expression is a poly expression. If its target type is known, its type is the type of its target type. If its target type is unknown, its type is computed by combining the types of each switch labels. Consider the following snippet of code:

    This switch expression has a target type of double, which is the type of the value variable. Therefore, the type of the switch expression is double. The compiler also checks that the type of the value yielded from each switch label is assignment compatible to the target type of the switch expression. In this case, the switch labels yields an int (10), a double (20.4) and a float (1.5F). All three types, int, double, and float, are assignment compatible to the target type double.
    Consider the following snippet of code. Will it compile?

    This snippet of code does not compile. The target type of the switch expression is int, which is the declared type of the value variable. The double and float values yielded from the two switch labels are not assignment compatible to int. This is the reason why this code does not compile.
    Consider the following snippet of code. Will it compile?

    The code compiles fine. Notice the use of var to declare the value variable. This time, the target type of the switch expression is unknown. The compiler has to compute the type of the switch expression by looking at each switch label. The switch labels yield values of int, double, and float type. The compiler uses the type-widening rules and computes double as the type of the switch expression. Remember that the compiler has to infer the type of the value variable because of var. The type value will be inferred as double, which is the same as the computed type of the switch expression.
    Consider the following snippet of code. Will it compile?

    If you guessed that this snippet of code won't compile, you are wrong. It compiles fine. Now you might be curious to know the computed type of the switch expression. The compiler uses the following steps:
  • There are three types of values yielded from switch labels: int, double, and String.
  • The types are mixed–two primitive types and one reference type.
  • The primitive types are promoted to reference types Integer and Double.
  • The compiler looks at the common types among Integer, Double, and String. The compiler computes a type that is the union of all common types of these three types. All three types implement four interfaces: Serializable, Comparable, Constable, and ConstantDesc. The computed type of the switch expression is a combination of these four interfaces.

  • So, what is the type of the switch expression in the previous snippet of code? Here it is:

    This is a non-denotable type. That is, only the compiler can use this type in bytecode. You cannot use (or denote) this type in your source code. To see this for yourself, you can use JShell to run this snippet of code. Make sure to use the --enable-preview option to start Jshell and set the feedback mode to verbose, as shown:


    The yield Statement
    The new switch expression has introduced a new statement called the yield statement. Making yield a statement has some implications on the existing code. It might break existing code if you had a yield() method, which was invoked using unqualified syntax. Let us take an example to understand this rule. Consider the followings yield statement:

    Before yield being a statement, this was definitely a method call. That is, it will call a method named yield by passing a value 10.
    After the introduction of the switch expressions, this statement will be interpreted as a yield statement that yields a value 10 and it is only permitted to be used in switch expressions. Note that using parenthesis around 10 does not make this a method call because now yield is a statement and (10) is its value. All of the following variants will be treated as a yield statement–whitespaces and parenthesis making no difference:

    If you have unqualified yield() method calls in your existing code, you will need to modify it to make them qualified method calls. That is, if you have yield(x) in your existing code, you will need to change it to this.yield(x) or C.yield(x) depending on the context.
    With the introduction of the switch expressions, yield is a restricted identifier.  Its use is restricted in certain contexts. You cannot use yield as a type name such as a class name or an interface name. However, you can use yield as a method name and a variable name. Using yield as a method is allowed for backward compatibility because the Thread class in Java contains a yield method and, in rare cases, you might have named your methods as yield.
    The following is a complete program to show how to use yield as a method/variable names and how to call such methods. You must use the NoYieldAsTypeName.yield() syntax to call the yield() method.



    Output:


    Mixing Switch Label Syntax
    You have two syntax to declare switch labels–one uses a colon (:) and one uses an arrow (->). In one switch, you cannot mix the two syntax. The following snippet of code does not compile:

    2 years ago
    Hello Rob,
    I have revised the "Java 9 Revealed" title. The publisher is working on incorporating the changes into the print and electronic editions. For old versions, errata will be provided. Changes in this revision are:

    1. The HTTP/2 Client API
    2. The --illegal-access option for the java command
    3. Naming for automatic modules
    4. Auto-completion in JShell

    Anyone interested in the latest source code may download it from this link:
    https://drive.google.com/file/d/0B2KU1YPfvFdnWEJvV1Uyd2tBR2s/view?usp=sharing

    The official version of the source code, errata, and the revised text will be published shortly at the Apress site at:

    http://www.apress.com/us/book/9781484225912

    Note:
    It is a partial revision of the book. For example, you will still find "version 9-ea" in command's output (instead of "version 9") as the JDK version number.

    Thanks
    Kishori
    4 years ago
    Hello Rahul,

    >> However, what do think would be the extent of its capability ? Is it able to provide a truly immersive Java environment for possibly most of the capabilities that java provides as a language
    >> or is it preferable to just use the REPL to test out individual snippets of logic, see if they react the way we want them to and then create fully functional classes and perform unit testing on the go ?

    JShell provides a true Java environment. You can use any Java language feature in JShell that you can use in a regular Java program. It is meant for exploring the Java language and developing a quick prototype, not to develop an application. For example, you can have a top-level function in JShell, but the Java language does not support a top-level function. A top-level function allows you to quickly test a static method in a class. JShell also allows you to load the source code you already written or use the existing compiled code.
    4 years ago
    I would like to thank JavaRanch for giving an opportunity to promote my book. Thanks to everyone for asking great questions and participating in this promo event.

    Thanks
    Kishori
    4 years ago
    Hello Sundar,

    >> Has this feature been enabled by default and is it possible that can it be switched off using some run
    >> time settings to a char[] backed implementation/revert to storing all the Strings as UTF-16?
    Yes. This feature is enabled by default. There is no way to switch to char[] implementation that I known of. It is an internal change, so there are no changes in the way String class and its companion classes work.

    >>If StringBuilder and StringBuffer are now also backed by a byte[] to match the String implementation.
    Yes.

    >>Any recent benchmark on this new improvement?
    The prototypes using compact strings have confirmed reduction in memory footprint. Here are few results, which are over two years old:

    1. http://cr.openjdk.java.net/~shade/density/state-of-string-density-v1.txt
    2. http://cr.openjdk.java.net/~huntch/string-density/reports/String-Density-SPARC-jbb2005-Report.pdf
    4 years ago
    Hello Rahul,
    Thread Management Improvements:
    I do not know of any notable Thread API improvements in JDK 9. Of course, the JDK team constantly work on improving threads performance in each version - one such improvement can be found at
    http://openjdk.java.net/jeps/143

    Java SE 9 has add few methods to CompletableFuture API.

    Private Package and OO
    Private packages in modules provide encapsulation, which helps library developers and greatly the JDK developers to keep the implementations of public APIs private, so they can change the implementation without affecting the public API and most importantly without affecting the users of the public APIs. Up to JDK 8, nothing stops developers from using JDK- internal classes, which were supposed to be private and meant to be used by only JDK. In JDK 9, those JDK- internal APIs are in private packages in JDK modules. You can still use JDK-internal APIs in JDK 9, but you have to make an extra effort to do so realizing that you are at risk by using those APIs because JDK implementers may change them in future.

    Another main benefit of modules is dependency declaration and validation. One module can declare dependency on other modules. At startup, the JVM verifies that all dependencies of a module are also available; otherwise, the app fails to start. This is a significant improvement from JDK 8 where there was no dependency management for your application; an attempt to load a type was made at runtime when the type was needed - making the app fail at runtime when types are missing.

    Another benefit is to have a custom compact runtime image. If you application uses only java.base module, you can create a custom image for your application, which is about 20 MB in size. You can supply your users that custom image and your users do not need to install full JRE. This is a kind of byproduct of modules, where you have an option to distribute only modules that are needed by your app, instead of the full JRE. Compact profiles in earlier version was an attempt to achieve this goal. However, modules with custom runtime image features in JDK 9 gives you finer controls.  

    REPL
    My book contains a chapter on REPL spanning over 60 pages. All REPL features have been discussed in the book.

    The JShell tool in JDK 9 lets you execute as snippet of Java code. You have used the term "function" in your query. As you know, Java does not support standalone functions. It supports methods. However, REPL lets you define top-level functions as you would declare in C and let you call from other places such as another top-level functions or methods or other classes. Behind the scene, all top-level function become static methods in a dynamically generated class. All free-standing variables become static variables of the dynamically declared internal class. However, all these things are transparent to the users. You get an impression that you can declare global variables and functions without declaring a class.

    In Java, the following expression is not allowed:



    You cannot compile this expression in a complete Java program. However, JShell allows you to enter such expressions. Internally, it declares a variable of appropriate type and assigns the evaluated value of the expression to that variable.

    JShell imports most commonly used types for you, so you

    REPL has been introduced to explore the Java programming language without writing the boilerplate code for a complete program. To this end, you do not have to add a semicolon to end a statement. JShell detects the completion of a statement for you and executes it. Here are few examples of JShell that are related to your query:





    Thanks
    Kishori
    4 years ago