Five Features to Make Java Even Better
I stumbled upon this proposal by Brian Goetz for data classes in Java, and immediately realized that I too have a few ideas about how to make Java better as a language. I actually have many of them, but this is a short list of the five most important.
Global Variables. There are Singletons in Java, which, as we all know, are nothing but global variables. Wouldn’t it be great to enable global variables in Java and get rid of Singletons. PHP, JavaScript, Ruby and many other languages have them, why doesn’t Java? Look at this code:
class User { private static final User INSTANCE; private User() {} public static User getInstance() { synchronized (User.INSTANCE) { if (User.INSTANCE == null) { User.INSTANCE = new User(); } } return User.INSTANCE; } public String getName() { // return user's name } }
Then, to access it we have to use:
String name = User.getInstance().getName();
This is a Singleton. See how verbose it is? We can simply replace it with a global variable (global
is the keyword I’m suggesting we use):
global User user;
And then:
user.getName();
Much less code to write, and way easier to read!
Global Functions and Namespaces
To group static methods together we create utility classes, where we have to define private constructors to prevent their instantiation. Also, we have to remember which particular utility class a static method is in. It’s just extra hassle. I’m suggesting we add global functions to Java and optional “namespaces” to group them. Take a look at this utility class:
class TextUtils { private TextUtils() {} public static String trim(String text) { if (text == null) { return ""; } return text.trim(); } }
Now look at this global function with a namespace:
namespace TextUtils { String trim(String text) { if (text == null) { return ""; } return text.trim(); } }
My point is that since we are already using classes as collections of functions, let’s make it more convenient. In some applications we won’t even need namespaces, just global functions, like in C and C++.
Full Access to Private Attributes and Methods
In order to access a private attribute or a method of an object from outside we have to use the Reflection API. It’s not particularly difficult, but it does take a few lines of code, which are not so easy to read and understand:
class Point { private int x; private int y; } Point point = new Point(); Field field = point.getClass().getDeclaredField("x"); field.setAccessible(true); int x = (int) field.get(point);
I’m suggesting we allow any object to access any of the attributes and methods of another object:
Point point = new Point(); int x = point.x;
Of course, if they are private, the compiler will issue a warning. At compile time you simply ignore the warning and move on. If you really care about encapsulation, pay attention to the warning and do something else. But in most cases programmers will ignore it, since they would happily use the Reflection API anyway.
NULL by Default
It would be convenient to let us call constructors and methods with an incomplete set of arguments. The arguments we don’t provide will be set to null
by default. Also, when a method has to return something, but there is no return
statement, Java should return null
. This is almost exactly how it works in PHP, Ruby, and many other languages. I believe it would be a convenient feature for Java
developers too.
monkeys
We won’t need to define so many methods when some of the arguments are optional. Method overloading is very verbose and difficult to understand. Instead, we should have one method with a long list of arguments. Some of them will be provided by the caller, others will be set to null
. The method will decide what to do, for example:
void save(File file, String encoding) { if (encoding == null) { encoding = "UTF-8"; } }
Then we just call either save(f)
or save(f, "UTF-16")
. The method will understand what we mean. We can also make it even more convenient, like it’s done in Ruby, providing method arguments by names:
save(file: f, encoding: "UTF-16");
Also, when there is nothing to return, the method must return null
by default. Writing return null
is just a waste of a code line and doesn’t really improve readability. Take a look:
String load(File file) { if (file.exists()) { return read_the_content(); } }
It’s obvious from this code that if the file exists, the method loads and returns its content. If not, it returns null
, which will be a good indicator for the caller that something is not right and the content of the file is not available.
Getters and Setters
I think it’s only obvious that we need this feature: every private attribute must automatically have a setter and a getter. There should be no need to create them, Java will provide them out-of-the-box, just like Kotlin and Ruby do. What is the point of having an attribute if there are no getters and setters to read it and to modify it, right?
With this new feature we’ll no longer need the help of Lombok, or IntelliJ IDEA.
Maybe I should turn my ideas into official proposals to JCP. What do you think?
You may also find these related posts interesting: Each Private Static Method Is a Candidate for a New Class; Try. Finally. If. Not. Null.; Why NULL is Bad?; Why Many Return Statements Are a Bad Idea in OOP; Can Objects Be Friends?;
Published on Java Code Geeks with permission by Yegor Bugayenko, partner at our JCG program. See the original article here: Five Features to Make Java Even Better Opinions expressed by Java Code Geeks contributors are their own. |
I personally would not want to see any of this ideas in java. These would bring the mess of python into java. Anyway I do not understand why people fear characters. More compact code means less readable code and when you have to maintain an old code, even if it is you who wrote it is pain to understand it. Singleton vs global variables: They would be used and abused for other purposes not just store objects which have to be global Global functions and namespaces: It can be really messy when some utility methods are defined as module level… Read more »
No, thanks! All of these serve very deliberate design choices and actually encourage good code design. Choice is all good and well, but just because something can be done doesn’t mean that it should be done. In fact I would consider Reflection API to access private variables and even Singleton Pattern an anti pattern that should be questioned when used instead of facilitated…
To each their own though!
Great article! helpful to know about java features which are still unknown to some of us, thanks for sharing.
Maybe the worst “improvements” I have ever heard of…
Tibor said it all, just have to add that Auto Getters and Setters is the worst idea ever.
A private field with no setter means “Don’t touch that”. Of course you can use reflection, but it’s a workaround and by no mean a default behavior. I personnaly very rarely use reflection, because it’s the best way to make an app unpredictable and hard to maintain, which is one the strength of Java: robustness.