Archive for the ‘Android Development’ Category

Java varargs suck

11/06/2012

TLDR; When using varargs in Java 1.6 be aware of problems that will arise when overloading methods that use varargs.

While playing around with Java (1.6) I started using varargs (denoted by type...) which allow you to call a method with variable number of arguments of a given type.

void foo(int... args) {
    for (int i : args) {
        System.out.println(i);
    }
}

foo(); // prints nothing
foo(1); // prints 1
foo(3, 2); // prints 3 & 2

Now, a simple question – before we go further – which method will the compiler use here?

void bar(int i) {} // method A
void bar(long l) {} // method B

bar(5);

Answer is, obviously, method ‘A’. Nothing spectacular: compiler has just chosen the more fitting overload (as in case of long it would have to perform implicit type widening).

Applying the same how-to-choose-an-overload logic we quickly create our overloaded varargs.

void oops(int... i) {} // method A
void oops(long... l) {} // method B

oops(5);

Which method will be chosen by compiler? A? Wrong! B? Wrong! Compiler can’t decide and tells us that it is ‘ambiguous’. Why? There is a bug in current Java implementation which makes the compiler (when deciding on overload) see this:

void oops(int[] i) {} // method A
void oops(long[] l) {} // method B

Which is semi-OK as when working with varargs we are actually dealing with arrays. The problem, however, is that Java doesn’t allow something like:

int[] a = new int[1];
long[] b = new long[1];
a = b; // !!! Error

This is because such assignment will only work with covariant types (if B extends/implements A, than a reference of array of Bs can be assigned to an array of As). In other words: Java tries to determine the proper meaning of ‘5’ (our magic number) and neither long, nor int fit as none of them can be used in both methods (so no meaning is narrower).

Sucks, doesn’t it? If you run into such problem I can only see one way of dealing with it. It isn’t pretty and it defeats the purpose of varargs (which is, IMHO, nifty syntax trick allowing you to call varargs methods easily without syntax boiler-plate). So here it is:

void oops(int... i) {} // method A
void oops(long... l) {} // method B

oops(new int[]{ 5 });

This bug should only appear in Java 1.6 and below, as from Java 1.7 it is fixed.

Advertisements

How to Quickly Jump on Java Wagon (Not Bandwagon!)

03/06/2012

TLDR; If you are an experienced developer and want to rapidly switch to Java, I recommend: “Sun Certified Programmer for Java 6” and “Effective Java“.

Having bought my first Android phone I decided it’s time to write some useful applications that I might use; which I couldn’t (!) find in Play Store.

As we all do know, the default language of Android Platform is Java (SE 6). Being an experienced (doesn’t translate to ‘veteran’ or ‘expert’) C/C++ programmer I needed sources of knowledge for someone who does understand OOP, OOA, OOD and all those fancy names that people come up these days. And so the quest for Java knowledge began…

I started with the “Java for Programmers“, as it sounded the most adequate. After reading a few of the first chapters I lost my motivation. All in all the book is decent, but it lacks details, important parts of the language are hidden somewhere inside chapters describing various parts of API (nested classes in chapter about GUI Components) and bits of OOA/OOD are thrown here and there making the book not as cohesive as I would like it to be.

Why not to try something harder, I asked. Knowing no fear I faced the “Java Language Specification“. It started … OK, I guess. I consumed chapter by chapter until the vision of yet another:

ReferenceType:
 ClassOrInterfaceType
 TypeVariable
 ArrayType
 ...

forced me to quit. Java spec isn’t the worst one (C++ was worse): it has quite a few real-code examples and with enough dedication you can read it all.

After reading several Java-related book reviews I’ve decided on “Sun Certified Programmer for Java 6“. It’s an amazing book that explains those truly tricky issues that arise when writing code yourself. There is also a lot of humor in the book, and you will be prepared to take the SCJP exam, if you’re interested.

The next step, before going straight to Android-centric docs, is to get yourself the all-time-favorite “Effective Java“. This is bible for every (serious) Java developer and even if it’s not the most up-to-date it’s still packed with crucial tips (reminds me of Lakos’ book).