Some of the weirdest Java puzzlers that we had a chance to get our hands on
Weird Java

Even the most experienced Java developers will find the questions in this post confusing. Or at the very least, amusing (And absolutely unfair). After our adventure with the Java Deathmatch we’ve decided to publish a different set of questions this time around, highlighting some of the unusual and quirky things you can do with Java. For the results of our previous quizzes, you can check out this post and see if you can solve the question that 4 out 5 of developers got wrong.

Do try this at home (or office). But please, please don’t use it in real life Java applications! Unless you’re trying to troll someone and in that case, everything goes. A huge huge thanks goes out to Peter Lawrey for sharing most of these questions with us. The solutions are available at the bottom of this post, but try giving them an honest try and see how many of them you manage to explain.

And the questions are…

1. Closing brackets are overrated

Oddly enough, the following piece of code compiles perfectly. But what does it print?

import static java.lang.Character.getNumericValue;

public class BigCharacters {
    public static void main(String...a‮) {
        for (char c‮ = 1; c‮ & gt; 0; c‮++)
            if (getNumericValue(c‮) & gt; 50)
                System.out.println(c‮ + ": " + getNumericValue(c‮));
    }
}

Note: getNumbericValue returns the numeric int value that the Unicode character represents. If the character doesn’t have a numeric value, -1 is returned.

Toto

2. The answer to life, the universe, and everything

Phew. We have our closing brackets back on this one. But what does the following code snippet print out? And why?

Integer a = 42;
Integer b = 42;
System.out.println(a == b);
Integer c = 666;
Integer d = 666;
System.out.println(c == d);

3. Char arithmetic

Moving on. Can you explain what is happening here?

char ch = '0';
ch *= 1.1;
System.out.println(ch);

Possible options:

a) Compiler error
b) Runtime error
c) Prints 0
d) Prints 4

4. Don’t give up!

This one is just out of this world. What’s going on here?

String _‎ = "Hello ";
String _‏ = "World";
String _‎‏ = " !!";
System.out.println(_‎+_‏+_‎‏);

Spoiler alert: It prints out “Hello World !!”

¯\_(ツ)_/¯

Ghost Busters

5. This question is self aware

What is the smallest value which prints WTF? The type of x is up to you.

if (x != (x += 0.0f))
System.out.println("WTF");

Solutions

1. Closing brackets are overrated

First, some background. There is a character encoded with \u202e which is used for Right to Left languages like Hebrew or Arabic, and makes the rest of the line appear in reverse order. It’s a zero width character, and not only that, it’s also valid to use as a Java identifier. Try copying the code snippet, move around your cursor and then you’ll notice where it appears in the code.

Other than RTL language support, it’s also very useful if you want to pull a prank on someone. Replace a closing bracket with an opening bracket that has this character behind it to reverse the rest of the line – And see what happens next. If you decide to do that, please send us a photo of the victim’s face 🙂

2. The answer to life, the universe, and everything

Integers are objects of course, as opposed to int which is a primitive type. However, this code snippet:

Integer a = 42;
Integer b = 42;
System.out.println(a == b);
Integer c = 666;
Integer d = 666;
System.out.println(c == d);

Prints out “true” for the first comparison and “false” for the next. This wouldn’t work for ints, but since Integers are separate objects it makes sense that c and d are not the same one. But why a == b?

The Integer type keeps a cache of all objects with a value in the range of -128 to 127 for performance reasons. So when you declare new variables in that range, you’re actually referring to the same object.

3. Char arithmetic

This code snippet prints out 4:


char ch = '0'; // ASCII for ‘0’ is 48
ch *= 1.1; // 48 x 1.1 is 52.8 which turns to 52 when cast to char
System.out.println(ch); // 52 represents ‘4’ in ASCII

4. Don’t give up!

How come _, _ and _ are different variables? You might have guessed it right. The answer is with hidden characters that pass on as legit Java identifiers. You can read more about it on Peter Lawrey’s blog right here.

5. This question is self aware

So what would make this expression to be evaluated as true?

if (x != (x += 0.0f))
System.out.println("WTF");

You can use any String, and also an int or long of (1 << 24) + 1 works for these types as their respective smallest value. But the smallest value of them all is Double.MIN_VALUE which is rounded to 0.0f when cast to a float.

Final Thoughts

We hope you enjoyed this collection of questions! However, if you find yourself spending too much time on puzzlers in your own codebase, it will probably be less than ideal. For these kind of situations, we’ve built OverOps for Java. OverOps is a Java agent that collects all the data you need to solve errors in production – WITHOUT going through log files and trying to recreate the state that caused them. It lets you see the variable values that cause errors, all across the stack, and overlays them on your code.

Java 8

Java 8 exceptions have never been so beautiful – Try OverOps for Java 8

OverOps variables

Some kind of monster @ OverOps, GDG Haifa lead.
  • Thibault Delor

    For the #5, on my machine, it works only if the variable x is declared as a Double (wrapper). If the variable is a double primitive it doesn’t work. Could you explain why? 😀

    • Peter Lawrey

      Double fails for a different reason. When you use != between any objects including wrappers it compares the references not their contents. Thus means Double.valueOf(0.0) != Double.valueOf (0.0) as this class has no caching. You should see the same with Float.

      You are right that it won’t fail for double as it’s the only type which is wider than a float. Eg long is not wider so it gets cast losing precision. For double it only fails for Nan.

  • http://javarevisited.blogspot.com/ Javin Paul

    I have faced the char arithmetic issue in past :-), same is true for String concatenation with integer, where order matters. Btw, I have also shared some tricky Java questions, your readers may find it interesting.

    • http://www.takipi.com/ Alex Zhitnitsky

      Thanks Javin! Good stuff

  • Gervais Blaise

    #1
    The funny thing is that a good text editor automatically convert the code to the left to right version.

    #2
    This is not guarantee. There is no requirements to implement this cache, so another JVM may produce other results.

    • Ulf

      #2: It’s part of the specification (so it’s an requirement).
      JLS 5.1.7 Boxing conversion: If the value p being boxed is […] an int or short number between -128 and 127 (inclusive), then let r1 and r2 be the results of any two boxing conversions of p. It is always the case that r1 == r2.

    • http://www.takipi.com/ Alex Zhitnitsky

      Thanks for the comment Geravis! Tried it both on IntelliJ and Eclipse, and they displayed it differently. Guess it depends on some text editor settings. Sublime for example showed it without all of the “madness”

  • Николай Лаптев

    Oracle provides us with its Java certifications. Passing them you will know all this cr*p and why it happens. Actually there is much more to get from there (e.g. modification of 1 element collection in foreach).

    • bytebuffer

      What’s with the 1-element collection modification? Can’t google anything weird about it. Can you share some links or elaborate on that?

      • Николай Лаптев

        Sorry, 2-element collection 🙂

        The following code can be run without problems. But if you change initial size to any other there will be concurrent modification exception. The sad thing is that it’s called a feature and not a bug.

        List listOfNull = new ArrayList();
        listOfNull.add(null);
        listOfNull.add(null);
        System.out.println(listOfNull.size());
        for(String nullString : listOfNull) {
        listOfNull.remove(0);
        }
        System.out.println(listOfNull.size());

        There are so many fun things in Java API.
        You can create local variable in one CASE statement and use it in another CASE statement.
        Unsigned math is mind blowing.
        Thread model is super dangerous to novice.

        I guess that is the reason Oracle try to educate people except of cause the reason of getting much more money 🙂

        • http://www.takipi.com/ Alex Zhitnitsky

          Hi Nikolai, thanks for sharing! If you’d like, we’d be happy to do another post like this with more examples. Please drop us an email on hello@takipi.com if you’d like to contribute to the blog.