Home > Enterprise >  Java System.console().charset() is undefined
Java System.console().charset() is undefined

Time:01-30

I'm reading Java, A Beginner's guide by Schildt, and on the IO chapter, when using a FileWriter class, he tries to use the constructor of the type FileWriter(String filename, Charset charset). For the charset he uses System.console().charset(). However, my VSCode tells me the method charset is undefined for Console object...

Is there a way to obtain the charset of the console?

CodePudding user response:

This book is showing you how to do it in the modern way. Whilst java-the-ecosystem makes a point of not changing everything every other year unlike some other programming language ecosystem, this did change, and changed, specifically, in the JDK17 release. 1

Starting with JDK17, this is the 'model' that the JVM uses to deal with charset encoding issues:

  • Every constructor and method in java that ends up converting bytes to characters or vice versa necessarily is going to use a charset (you need one to convert from bytes to character or vice versa, you can't not have one) - and they all have an overload (in all versions of java): You can either specify no charset in which case 'the default' would be used, or you could specify an explicit one. Starting with JDK17, all these methods use, as default, UTF-8, whether your host OS uses that as default charset or not. This is the change: Prior to JDK17, 'the default charset' meant the host OS charset. JDK17 and up, it means 'UTF-8'.

  • In the unlikely case you want to write data in the charset of the host OS, there's System.console().charset(). Therefore, new FileWriter("file.txt") would write in UTF-8, whereas new FileWriter("file.txt, System.console.charset()) would write in the host OS charset, whatever that might be. On linux it usually is UTF-8 and there's no difference; on windows it's more often something like Cp1252 or some such.

That's a change. Prior to JDK17, it worked differently:

  • Those use-default-charset methods/constructors, such as new FileWriter(fileName), would use the host OS charset. If you want UTF_8, you'd have to write new FileWriter(fileName, StandardCharsets.UTF_8).

  • There is no System.console.charset() method. It doesn't exist at all.

  • As an exception, all methods in the new files API (java.nio.file) default to UTF-8, even before JDK17.

Clearly then the JDK you told VSCode to use predates it (because it's telling you System.console().charset() does not exist. It was introduced in JDK17, conclusion: Your VSCode is using a JDK that predates this).

Unfortunately (I raised this point at the openjdk mailing lists, I don't think any openjdk team member cares, as nobody's taken any action on it), this means it is impossible to write code that works both pre- and post- JDK17 without jumping through some crazy hoops, if you want to write data explicitly in 'host OS charset' form.

As you said, you're a beginner, so presumably you don't particularly care about writing code that writes data using the host OS charset in a way that compiles on both pre- and post-JDK17.

Thus, pick a solution. Either one will work:

  1. Upgrade to JDK17.
  2. Use new FileWriter(fileName), without adding that charset.

I'd pick option #1 - the book is likely going to end up using other things introduced in JDK17, if it did so here.

NB: For a beginner's book, worrying about charset encoding is a bizarre choice, especially considering that evidently they thought it was okay to use the obsolete FileWriter, presumably to keep things simple. It's almost like someone who tries to explain how to drive a car taking a moment to explain how a carburettor works (waaaay too much detail, you don't need to know this when learning how to drive cars until much later), but sort of handwave away how to charge the car, which is relevant much earlier. Bizarre choice - consider it 1 minor demerit against this book, and know that this charset malarky is not what you should be worrying about right now, if your aim is to learn java.

[1] Congratulations - you are using a rather modern book. That's good news - a common problem is that tutorials are 20 years behind the times and end up showing you outdated ways of doing things. "Too new" is a better problem to have than "too old".

  •  Tags:  
  • java
  • Related