dcsimg
 

Using JShell in Java 9 in NetBeans 9.0, Part 3

Thursday Dec 20th 2018 by Deepak Vohra
Using JShell in Java 9 in NetBeans 9.0, Part 3

Learn how to run snippets for Java methods.

JShell is a command-line tool to run code snippets in a shell environment without having to compile and run a complete application. JShell is a new feature in Java 9. JShell could be used to test and debug code snippets when developing an application. JShell input should be in the form of a complete code snippet. We introduced JShell with two articles, "Using JShell in Java 9 in NetBeans 9.0, Part 1," and "Using JShell in Java 9 in NetBeans 9.0, Part 2," in which we discussed running the import statement, declaring and using variables, comparing Strings, and running statements. In this continuation article, we shall running snippets for Java methods. This article has the following sections:

Setting the Environment

Download and install NetBeans, as discussed in an earlier article. Launch JShell by selecting Tools>Open Java Platform Shell, as shown in Figure 1.

Tools>Open Java Platform Shell
Figure 1: Tools>Open Java Platform Shell

Using Methods

A method is declared in JShell just as it is in a Java application, with a few differences, which are also discussed in this section. As an example, declare a method triple(int) that takes an int argument and returns an int value.

int triple(int i) {
   return i*3;
}

Run the code snippet in JShell and a method gets created.

[10]-> int triple(int i) {
   return i*3;
}
|  created method triple(int)

Invoke the method triple with an int value as arg.

triple(1)

The argument value is tripled and returned.

[11]-> triple(1)
|  $13 ==> 3
[12]->

The method has a return type and parameters but no access modifier such as public, private, or protected. It is because a top-level method declaration, as all top-level declarations, is implicitly public. Any access modifier in a top-level method declaration is ignored. All of the following method declarations are equivalent to the preceding method declaration.

[1]-> private int triple(int i){
   return 3*i;
}
|  created method triple(int)
[2]-> protected int triple(int i){
   return 3*1;
}
|  replaced method triple(int)
[3]-> public int triple(int i){
   return 3*i;
}
|  replaced method triple(int)
[4]->

JShell displays compile-time errors, if any. As an example, make the return type of method triple as String and an error message is displayed.

[10]-> String triple(int i) {
   return i*3;
}
|  Error:
|  incompatible types: int cannot be converted to java.lang.String
|     return i*3;
|     ^-^

Modifying a Method Definition

An output message that would not be generated by a Java application and listed twice already in this section is "replaced method…". The message indicates that a method definition has been modified. The provision to replace/modify a method declaration and other declarations is to facilitate testing.

To modify or replace a method without defining a new method, the method signature, which is set by the method name and method parameters including the number of parameters and their type and order, must not be modified. As an example, declare a method hello with return type void and a String type parameter.

[4]-> void hello(String s){
}
|  created method hello(String)

Next, declare the same method hello with return type String, a String type parameter, and a return statement. The previous method declaration for hello gets replaced.

[5]-> String hello(String s){
   return "Hello " + s;
}
|  replaced method hello(String)
[6]->

Invoke the method hello(String) and the second method definition is invoked to output a "Hello John" message.

[6]-> hello("John")
|  $5 ==> "Hello John"
[7]->

The method arguments are concatenated in method invocation, if needed, as in the following snippet.

[7]-> hello("John"+" & "+"Johnny")
|  $22 ==> "Hello John & Johnny"
[8]->

In the preceding example of modifying a method, we replaced the return type void with String. Return does not have to be modified to replace a method. As an example, define a method hello as follows.

[15]-> String hello(String str1, String str2){
   return str1+str2;
}
|  created method hello(String,String)

Next, modify only the return statement. The method hello(String,String) gets replaced.

[16]-> String hello(String str1, String str2){
   return "Hello"+str1+str2;
}
|  replaced method hello(String,String)

As another example of running a method code snippet, define a method hello(String str1, String str2) with return type String[].

[17]->
String[] hello(String str1, String str2){
   return new String[]{str1,str2};
}
|  created method hello(String,String)

Invoke the method with two arguments to return an array.

[18]-> hello("John","Michael")
|  $39 ==> String[2] { "John", "Michael" }

Method Overloading

A method may be overloaded just as in a Java application. Declare a method hello(String s).

[1]-> String hello(String s){
   return "Hello  " + s;
}
|  created method hello(String)

Invoke the method to output a message.

[2]-> hello("John")
|  $1 ==> "Hello John"

Declare a different method hello(String,String).

[3]-> String hello(String str1, String str2){
   return str1+str2;
}
|  created method hello(String,String)

Invoke the method to output a message.

[5]-> hello("Hello"," John")
|  $16 ==> "Hello John"

Making a Forward Reference to a Method

JShell supports making forward references to a method. A forward reference invokes a method that has not yet been defined. Declare a method main(String) that makes a reference to a method hello(String), which has not yet been defined. The method main(String) does get created but it cannot be invoked until method hello(String) is defined.

[1]-> String main(String str){
   return "Hello "+hello(str);
}
|  created method main(String), however, it cannot be invoked until
|  method hello(java.lang.String) is declared

Invoke method main(String) and a message gets output, indicating that it cannot be invoked.

[2]-> main("Michael")
|  attempted to call method main(String) which cannot be invoked
|  until method hello(java.lang.String) is declared

Declare the method hello(String) that is referenced by main(String).

[3]-> String hello(String name){
   return name;
}
|  created method hello(String)

Subsequently, invoke method main(String) again and it gets invoked.

[4]-> main("Michael")
|  $1 ==> "Hello Michael"

The ";" is added implicitly if not added in top-level variable declarations and method declarations that are added one per line. But, the ";" is not implicit in statements within a method. As an example, declare the following method and an error gets output.

[1]-> int average(int i,int j){
   return (i+j)/2
}
|  Error:
|  ';' expected

Listing Methods

Methods defined in a given JShell session are listed with the /methods command. To demonstrate, define a few methods.

[1]-> int triple(int i) {
   return i*3;
}
|  created method triple(int)
[2]-> String hello(String s){
   return "Hello" + s;
}
|  created method hello(String)
[3]-> String hello(String str1, String str2){
   return str1+str2;
}
|  created method hello(String,String)
[4]-> int average(int i,int j){
   return (i+j)/0;
}
|  created method average(int,int)

Run the /methods command, and all the methods added get listed.

[5]-> /methods
|    printf (String,Object...)void
|    triple (int)int
|    hello (String)String
|    hello (String,String)String
|    average (int,int)int
[5]->

Modifiers Not Permitted in Top-level Method Declarations

Whereas modifiers public, private, and protected in top-level method declarations are ignored and a method definition is created implicitly with public access, certain other modifiers are not ignored and are not permitted in a top-level method declaration. These modifiers are not permitted at top level because these have significance within a certain context and not suitable in the context of JShell, which is to test code snippets.

The modifier static has significance when used with a method in the context of a class or an interface, but not at the top level. As an example, run the following method declaration that includes static.

[1]-> static String hello(String name){
   return "Hello "+name;
}
|  Warning:
|  Modifier 'static' not permitted in top-level declarations,
|  ignored
|  static String hello(String name){
|    ^----^
|  created method hello(String)

The static modifier is ignored, a Warning is output, but a method does get created. The method may be invoked.

[2]-> hello("John")
|  $1 ==> "Hello John"
[3]->

Similarly, the modifier final does not have significance at the top level, whether in a method declaration or any other declaration, because JShell is designed to run code snippets dynamically and declaring a method (or variable, or class) final would make the snippet unmodifiable. As an example, add the final modifier to a method. The final modifier is ignored, a Warning is generated, and the method definition is created without the final.

[2]-> final int triple(int i){
   return 3*i;
}
|  Warning:
|  Modifier 'final' not permitted in top-level declarations,
|  ignored
|  final int triple(int i){
|    ^---^
|  created method triple(int)

Invoke the method and it outputs a result.

[3]-> triple(5)
|  $1 ==> 15
[4]->

Some other modifiers also are not permitted at the top level, whether in a method or any other declaration. Whereas modifiers static and final are ignored and a method definition created, modifiers abstract and native in a top-level method generate an error and a method does not get created.

[1]-> abstract String hello(String s){
   return "Hello "+s;
}
|  Error:
|  Modifier 'abstract' not permitted in top-level declarations
|  abstract String hello(String s){
|    ^------^
[1]->

[1]-> native String hello(String s){
   return "Hello "+s;
}
|  Error:
|  Modifier 'native' not permitted in top-level declarations
|  native String hello(String s){
|    ^----^

Modifiers default and synchronized in a top-level method declaration or any other declaration also are not permitted and generate an error.

Conclusion

In this article, we discussed running code snippets for Java methods in JShell. In a subsequent article, we shall discuss running code snippets for Java classes, interfaces, and arrays.

Home
Mobile Site | Full Site