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 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 monkeys developers too.
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?
Programming languages are...
— Yegor Bugayenko (@yegor256) May 30, 2021