5

Why does my jshell instance (JDK Version 9-ea) unable to identify printf() statement ? Below is the error I observe,

jshell> printf("Print number one - %d",1)
|  Error:
|  cannot find symbol
|    symbol:   method printf(java.lang.String,int)
|  printf("Print number one - %d",1)
|  ^----^

I am able to access printf, provided I specify it in a regular way.

jshell> System.out.printf("Print number one - %d",1)
Print number one - 1$1 ==> java.io.PrintStream@1efbd816

Any pointers?

ZhekaKozlov
  • 36,558
  • 20
  • 126
  • 155
R K
  • 1,283
  • 1
  • 14
  • 41

4 Answers4

7

An earlier version of JShell had a printf method pre-defined but it was removed from early access builds. You can of course define your own printf method:

jshell> void printf(String format, Object... args) { System.out.printf(format, args); }

Or you can get the printing methods that were in earlier builds back by starting JShell with:

jshell --start DEFAULT --start PRINTING

(If you use only --start PRINTING you won't get the default imports.)

For more information see bug JDK-8172102 in the Java bug database and changeset b2e915d476be which implemented it.

David Conrad
  • 15,432
  • 2
  • 42
  • 54
1

Java is an object-oriented language and you cannot call a non-static method without an object associated with this method. printf is a non-static method of the class PrintStream and you cannot call it without a PrintStream instance.

There are some PrintStream instances in the standard Java library like System.out and System.err, so you can call System.out.printf() or System.err.printf(), but plain printf() does not work because jshell does not know which object this printf() belongs to.

ZhekaKozlov
  • 36,558
  • 20
  • 126
  • 155
  • 1
    This would be true of Java in general but it isn't true of JShell. You can define a method without defining a class, and JShell used to define a printf method, although it's no longer defined by default. – David Conrad May 09 '17 at 07:58
  • @DavidConrad All methods defined in jshell are implicitly static. That's why you can call them without objects. – ZhekaKozlov May 10 '17 at 04:22
  • It's not about being able to call them without objects but to define them without an enclosing class. You can't have a method, even a static method, outside a class in Java. But presumably JShell has some default class that it makes them methods of. – David Conrad May 10 '17 at 07:16
  • @DavidConrad Yes, there is an implicit enclosing class in `jshell`. If you write `class A {}` in `jshell`, then `A.class.getEnclosingClass() != null` will return `true`. – ZhekaKozlov May 10 '17 at 07:51
0

Does it simply work without jshell? This can't work like this, since there is no such method defined outside PrintStream.

You could define your own printf like this:

jshell> private  void printf(String s) { System.out.println(s); }

And later use it :

jshell> printf("test")
test
Eugene
  • 117,005
  • 15
  • 201
  • 306
0

This might be more convenient:

jshell> /set start -retain DEFAULT PRINTING

(Need to set this once. Next time you can simply start jshell without any argument). See official jshell documentation.

rmuller
  • 12,062
  • 4
  • 64
  • 92