Core Java

Java, if this were a better world

Just a little dreaming about a better world, where some old blunders in the Java platform would’ve been corrected and some awesome missing features would’ve been implemented. Don’t get me wrong. I think Java is awesome. But it still has some issues, like any other platform. Without any particular order, without claiming to be anything near exhaustive, and most importantly, without claiming to be well thought-through and entirely correct, I wish for these things:

Serialisability

Within an object, serialisability is the default. If you don’t want a member to be serialisable, you mark it “transient”. Why on earth do we have to add this silly marker
 
interface “Serializable” to all of our classes?

All objects should be Serializable by default. Non-serialisability should be the “feature” that is marked explicitly

Of course, serialisability itself has a lot of weird details that I won’t go into, here

Cloning

Since all objects should be Serializable by default,

All objects should also be Cloneable by default. Non-cloneability should be the “feature” that is marked explicitly

Besides, shallow cloning is hardly ever useful. Hence

All objects should deep-clone themselves by default. Shallow cloning can be implemented explicitly

Note, the clone method should be some native method in java.lang.System or some other utility. It shouldn’t be on java.lang.Object, allowing client code to implement their proper interpretation of cloning, without any accidental name clashes. Alternatively, similar private callback methods could be implemented, the same way that this is done for serialisation, if cloning should be customised.

Unsigned numbers

Why isn’t this part of Java?

There should be an unsigned version of all integer primitives, as well as java.lang.Number wrappers

Primitives

Primitives are a pain to support in APIs. int and Integer should be the same from a syntax perspective. int[] and Integer[] should be, too

Primitives and their wrappers should be better integrated in the language and in the JVM

This one is probably not really resolveable without giving up on the performance advantage that true primitives offer. See Scala…

Properties

Getters and setters aren’t really state-of-the-art.

Properties should be supported more formally

See also a recent article and its comments on this blog: http://blog.jooq.org/2013/01/12/bloated-javabeans-part-ii-or-dont-add-getters-to-your-api/

Collections

The collection API should be better integrated with the language. Like in many other languages, it should be possible to dereference collection contents using square brackets and curly braces. The JSON syntax would be an obvious choice. It should be possible to write:

// Translates to new ArrayList<>(...);
List<Integer> list = [ 1, 2, 3 ];

// Translates to list.get(0);
Integer value = list[0];

// Translates to list.set(0, 3);
list[0] = 3;

// Translates to list.add(4);
list[] = 4;

// Translates to new LinkedHashMap<>(...);
Map<String, Integer> map = { 'A': 1, 'B': 2 }; 

// Translates to map.get(0);
Integer value = map['A']

// Translates to map.put('C', 3);
map['C'] = 3;

ThreadLocal

ThreadLocal can be a nice thing in some contexts. Probably, the concept of ThreadLocal isn’t 100% sound, as it can cause memory leaks. But assuming that there were no problems,

threadlocal should be a keyword, like volatile and transient

If transient deserves to be a keyword, then threadlocal should be, too. This would work as follows:

class Foo {
  threadlocal Integer bar;

  void baz() {
    bar = 1;           // Corresponds to ThreadLocal.set()
    Integer baz = bar; // Corresponds to ThreadLocal.get()
    bar = null;        // Corresponds to ThreadLocal.remove()
  }
}

Of course, such a keyword could be applied to primitives as well

References

References are something weird in Java. They’re implemented as Java objects in the java.lang.ref package, but treated very specially by the JVM and the GC.

Just like for threadlocal, there should be keywords to denote a reference

Of course, with the introduction of generics, there is only little gain in adding such a keyword. But it still feels smelly that some classes are “very special” within the JVM, but not language syntax features.

Reflection

Please! Why on earth does it have to be so verbose?? Why can’t Java (Java-the-language) be much more dynamic? I’m not asking for a Smalltalk-kind of dynamic, but couldn’t reflection be built into the language somehow, as syntactic sugar?

The Java language should allow for a special syntax for reflection

Some pain-easing can be achieved on a library-level, of course. jOOR is one example. There are many others.

Interfaces

Interfaces in Java always feel very weird. Specifically, with Java 8?s extension methods, they start losing their right to exist, as they move closer to abstract classes. Of course, even with Java 8, the main difference is that classes do not allow multiple inheritance. Interfaces do – at least, they allow for multiple inheritance of specification (abstract methods) and behaviour (default methods), not for state.

But they still feel weird, mainly because their syntax diverges from classes, while their features converge. Why did the lambda expert group decide to introduce a default keyword?? If interfaces allow for abstract methods (as today) and concrete methods (defender methods, extension methods), why can’t interfaces have the same syntax as classes? I’ve asked the expert group with no luck: http://mail.openjdk.java.net/pipermail/lambda-dev/2012-August/005393.html. Still, I’d wish that…

Interface syntax should be exactly the same as class syntax, wherever appropriate

This includes static methods, final methods, private methods, package-private methods, protected methods, etc.

Default visibility

Default visibility shouldn’t be specified by the absence of a private/protected/public keyword. First of all, this absence isn’t dealt with the same way in classes and interfaces. Then, it is not very readable.

Default visibility should be specified by a “package” or “local” or similar keyword

Literals

This would be an awesome addition in everyday work.

There should be list, map, regex, tuple, record, string (improved), range literals

I’ve blogged about this before: http://blog.jooq.org/2012/06/01/array-list-set-map-tuple-record-literals-in-java/. Some ideas mentioned by Brian Goetz on the lambda-dev mailing list were found here: http://mail.openjdk.java.net/pipermail/lambda-dev/2012-May/004979.html

#[ 1, 2, 3 ]                          // Array, list, set
#{ 'foo' : 'bar', 'blah' : 'wooga' }  // Map literals
#/(\d+)$/                             // Regex
#(a, b)                               // Tuple
#(a: 3, b: 4)                         // Record
#'There are {foo.size()} foos'        // String literal

I’ll add

#(1..10)                              // Range (producing a List)

Final

Methods, attributes, parameters, local variables, they can all be declared as “final”. Immutability is a good thing in many ways, and should be encouraged (I’ll blog about this, soon). Other languages, such as Scala, distinguish the “val” and “var” keywords. In addition to those other languages’ impressive type inference capabilities, in most cases, val is preferred to var. If one wants to express a modifiable variable, they can still use “var”

Final should be the default behaviour for members, parameters and local variables

Override

It is dangerous to accidentally override a method. Other languages have solved this by causing compilation errors on overrides

An override keyword should be introduced to explicitly override a method

Some Java compilers (e.g. the Eclipse compiler) can be configured to emit a warning / error on the absence of the java.lang.Override annotation. However, this really should be a keyword, not an annotation.

Modules

Dependency management is a nightmare in Java. There is one other language, that builds compilation units in terms of modules: Fantom. Stephen Colebourne (the JodaTime guy) is a big fan of Fantom, and has held a speech at Devoxx. He also blogs about Fantom, from time to time: http://blog.joda.org/search/label/fantom

A compilation unit should be expressed in the form of a “module” / jar file

This would of course make Maven obsolete, as the Java compiler could already handle dependencies much better.

Varargs and generics

Come on. @SafeVarargs?? Of course, this can never be resolved entirely correctly, due to generic type erasure. But still

There should be no generic type erasure

Tuples and Records

I really think that this is something missing from Java

There should be language support for tuples and records

Scala has integrated tuples up to a degree of 22, .NET supports tuples up to a degree of 8. This would be a nice feature in the Java language as well. Specifically, records (or structs) would be a nice thing to have. As mentioned before, there should be literals for tuples and records, too. Something along these lines:

#(a, b)                               // Tuple
#(a: 3, b: 4)                         // Record

Compiler

A compiler API that goes far beyond adding some annotation processing would be nice. I’d love to be able to extend Java-the-language itself. I’d like to embed SQL statements directly into Java code, similar to SQL being embeddable in PL/SQL. Of course, such SQL code would be backed by a library like jOOQ.

The compiler API should allow for arbitrary language extension

Of course, this improved compiler API should be done in a way that auto-completion, syntax highlighting and other features work automatically in IDEs like Eclipse, as the compiler extensions would be able to expose necessary artefacts to IDEs. OK, I agree, this improvement is a lot of dreaming

Type inference

If unambiguous, couldn’t type inference just be as powerful as Scala’s? I don’t want to write down the complete type of every local variable. Scala’s local type inference should be supported

Operator overloading

OK, this is a highly religious topic. Many of you won’t agree. But I just like it

Java should support operator overloading

Some library operations are just better expressed using operators, rather than methods. Think of BigInteger and BigDecimal’s horribly verbose API.

Any other ideas? Add comments!

Of course, lambdas and extension methods are missing and generics are erased. While the latter will never be fixed, the first will be in Java 8. So lets forgive Sun and Oracle for making us wait so long for lambdas
 

Reference: Java, if this were a better world from our JCG partner Lukas Eder at the JAVA, SQL, AND JOOQ blog.

Lukas Eder

Lukas is a Java and SQL enthusiast developer. He created the Data Geekery GmbH. He is the creator of jOOQ, a comprehensive SQL library for Java, and he is blogging mostly about these three topics: Java, SQL and jOOQ.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

8 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Sergei
11 years ago

WTF? Serializable and Cloneable very dangerous interface, once you publish you API, where class implemented serializable you can’t change it easily! More precisely it described in Effective Java by Joshua Bloch.

LukasEder
LukasEder
11 years ago
Reply to  Sergei

Do you mean that the class cannot be changed easily anymore? Why, because someone really clever thought that they ought to persist a serialised Java object on a disk for 15 years before deserialising it again? :-)

Sergei
11 years ago
Reply to  LukasEder

Firstly, yes. Someone, who use your library just update version and his production server lost important information, for example.

Now, imagine large java object (or simple thing, similar with linked list), it serialize recursively, one more unexpected Stack Overflow exception. Do you really want think about writeObject method for every class?

And, of course, security. Serializable can easyly break security of you classes. For example, you can modify inner state of your immutable objects!

Alessandro Martin
11 years ago

So , in a better world, Java would be Python? :D

Serhiy Palamarchuk
11 years ago

Looking into the post it would be Python + Ruby + .NET + Javascript + … and many more. :D

LukasEder
LukasEder
11 years ago

Why, yes. Stealing only the best ideas off of everyone.

dapeng liu
dapeng liu
11 years ago

type inference is so common these days … java should have it also, doesn’t make sense to me to tell the compiler twice about the type of my variable. String hello = “world”;

LukasEder
LukasEder
11 years ago

In the end, you’re probably right. I didn’t think all of this through very well (as I stated in my disclaimer). So the few advantages of making everything serialisable might indeed cause more problems in the end…

Back to top button