share
Stack OverflowHidden Features of Java
[+295] [100] grom
[2008-08-19 01:36:03]
[ java ]
[ https://stackoverflow.com/questions/15496/hidden-features-of-java ]

After reading Hidden Features of C# [1] I wondered, What are some of the hidden features of Java?

(17) Note that it's not always a great idea to use these hidden features; often times they are surprising and confusing to others reading your code. - Kevin Bourrillion
(1) You (/someone) should probabbly sum up the answers neatly in the question body like the C# question. - ripper234
[+432] [2008-08-19 20:09:17] Boris Terzic

Double Brace Initialization [1] took me by surprise a few months ago when I first discovered it, never heard of it before.

ThreadLocals [2] are typically not so widely known as a way to store per-thread state.

Since JDK 1.5 Java has had extremely well implemented and robust concurrency tools beyond just locks, they live in java.util.concurrent [3] and a specifically interesting example is the java.util.concurrent.atomic [4] subpackage that contains thread-safe primitives that implement the compare-and-swap [5] operation and can map to actual native hardware-supported versions of these operations.

[1] http://www.c2.com/cgi/wiki?DoubleBraceInitialization
[2] http://docs.oracle.com/javase/6/docs/api/java/lang/ThreadLocal.html
[3] http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/package-summary.html
[4] http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/atomic/package-summary.html
[5] http://www.ibm.com/developerworks/java/library/j-jtp11234/

It's too bad my IDE (NetBeans) formats them horribly when it's auto-formatting. - Allain Lalonde
(40) Double-brace initialization... weird... I'd be wary of adopting that particular idiom too widely though, since it actually creates an anonymous subclass of the object, which could cause confusing equals/hashcode problems. java.util.concurrent is a truly great package. - MB.
(6) I have taught Java, and this is the very first time I've come across this syntax... which goes to show you never stop learning =8-) - Yuval
Note that the compiler generates an AnonymousInnerClass to implement Double Brace Initialization, therefore it only works for non-final classes. Which is a shame, since literal initializations are often inteneded as constants. - Chris Noe
(49) Note that if you retain a reference to a collection initialized with this "double brace" idiom (or if we call it by its real name - annonymous class with initializer block), you implicitly hold a reference to the outer object which can cause nasty memory leaks. I'd recommend avoiding it altogether. - ddimitrov
(51) "Double-brace initialization" is a very euphemistic name for creating an anonymous inner class, glossing over what's really happening and making it sound as if inner classes were intended to be used this way. This is a pattern I'd prefer remain hidden. - erickson
I have to admit this is the first time I've seen double braces in Java. Great tip!!! - Stephane Grenier
(4) To make sure I understand, the double brace creates an anonymous inner class, then creates a static block inside it, which then lets you execute methods from a static context. Correct? - Drew
(11) Almost, it is not really a static block but an "initializer block" which is different since it gets executed at a different time (see the link I put in the answer for more details) - Boris Terzic
(1) This is probably OK if used occasionally, but if you encourage everyone to do it, your project will get littered with lots of spurious anonymous classes before you know it. For example, going via Arrays.asList() for initialising a hash set is generally preferable. - Neil Coffey
This is also known as "crazybob's contraption." Though I can't find the origin of that name, google finds multiple uses. - Chadwick
(1) Although the double brace thing is interesting--I'd say it's really not worth it. At the very least you are mixing data in with code--always a bad idea. To keep size down, an even smaller version of their example would be: String initial = new String[]{"XZ13s","AB21/X","YYLEX","AR2D"}; then just use initial in a loop of "adds". This has the added advantage that your data is 95% extracted and would then be trivial to move out of your code completely. Creating String arrays is a very light syntax and great for keeping your code and data from getting too intimate. - Bill K
Don't like it, I find it a bit horrendous to create an an anonymous subclass for no reason :) - Chris Dennett
"Double Brace Initialization" is really three separate concepts. They are unrelated, except for having similar syntax, so I'm not sure why we've invented a term that covers all three. Developers should understand that they are code constructs with different uses. They are: anonymous class declaration: new Object() {}, the initializer block: class MyObject { int x; { x=0; /*initializer block doesn't have to be static*/ } }, and array literal notation: new Object[]{ "One", "Two", "Three" }. I wouldn't call any of these an anti-pattern, though use of anonymous classes should be limited. - RMorrisey
I use it a lot for JMock expectations. I have not seen any other need for it. - Wim Deblauwe
I found double brace initialization very useful in creating some complex JAXB objects. For example I've had a task to create a SID(Shared Information/Data Model) XML using JAXB, and it became 10 times more intuitive and easy using double brace initialization. Here's an example: pastebin.com/29wiyGhj - bezmax
1
[+279] [2008-09-03 21:51:46] Apocalisp

Joint union in type parameter variance:

public class Baz<T extends Foo & Bar> {}

For example, if you wanted to take a parameter that's both Comparable and a Collection:

public static <A, B extends Collection<A> & Comparable<B>>
boolean foo(B b1, B b2, A a) {
   return (b1.compareTo(b2) == 0) || b1.contains(a) || b2.contains(a);
}

This contrived method returns true if the two given collections are equal or if either one of them contains the given element, otherwise false. The point to notice is that you can invoke methods of both Comparable and Collection on the arguments b1 and b2.


My favourite use for this is when you need a method that accepts an Appendable Charsequence. - Neil Coffey
(5) Is it possible to have an "OR" there instead of the &? - mainstringargs
(9) @Grasper: No, OR (disjoint union) is not provided in that context. But you can use a disjoint union datatype like Either<A, B> instead. This type is the dual of a Pair<A, B> type. Look at the Functional Java library or the Scala core libraries for an example of such a datatype. - Apocalisp
(5) You should said that you MUST extends only one class and several interfaces -> public class Baz<T extends Clazz & Interface1 & InterfaceI... and not class Baz<T extends Clazz1 & ClazzI> - JohnJohnGa
2
[+219] [2008-09-06 14:27:50] David Carlson

I was surprised by instance initializers the other day. I was deleting some code-folded methods and ended up creating multiple instance initializers :

public class App {
    public App(String name) { System.out.println(name + "'s constructor called"); }

    static { System.out.println("static initializer called"); }

    { System.out.println("instance initializer called"); }

    static { System.out.println("static initializer2 called"); }

    { System.out.println("instance initializer2 called"); }

    public static void main( String[] args ) {
        new App("one");
        new App("two");
  }
}

Executing the main method will display:

static initializer called
static initializer2 called
instance initializer called
instance initializer2 called
one's constructor called
instance initializer called
instance initializer2 called
two's constructor called

I guess these would be useful if you had multiple constructors and needed common code

They also provide syntactic sugar for initializing your classes:

List<Integer> numbers = new ArrayList<Integer>(){{ add(1); add(2); }};

Map<String,String> codes = new HashMap<String,String>(){{ 
  put("1","one"); 
  put("2","two");
}};

It'd probably be more legible to have a method that all your constructors invoked, or to have all the constructors invoke a root one this(...) as opposed to super(...) - Allain Lalonde
It's good to know that checked exceptions thrown in anonymous initializers need to be declared by the constructors. Static initializers cannot throw checked exceptions. - Tom
(38) The advantage of this over an explicit method that needs to be called is that if someone adds a constructor later they don't need to remember to call init(); that will be done automatically. This can prevent errors by future programmers. - Mr. Shiny and New 安宇
(40) Also, unlike an init() method, it can initialize final fields. - Darron
(2) What if you extend the class and instantiate various children? Will it still behave in the same manner? - Kieran Senior
(12) People often dis certifications (e.g. stackoverflow.com/questions/281100/281127#281127) and especially question their technical merits. But if more programmers here had studied for their SCJP, this would not be considered a "hidden feature" by so many. ;-) - Jonik
(12) I bet even "java in 24 hours" book has this "obvious feature". read more guys :)( - Özgür
@Jonik I studied for my SCJP and remember seeing this, but had long forgotten about it. It was a nice refresher to see it posted in this thread ... not a technique you see used every day. - JasonStoltz
(1) It's important to note that, since instance initializer blocks run before constructors, they also run before superclass constructors are called - salezica
3
[+201] [2008-09-11 01:15:19] Kevin Wong

JDK 1.6_07+ contains an app called VisualVM (bin/jvisualvm.exe) that is a nice GUI on top of many of the tools. It seems more comprehensive than JConsole.


And it has a plugin (it is an netbeans thingie) that allows it to use Jconsole plugins. Quite nice. - Thorbjørn Ravn Andersen
VisualVM is the best thing since sliced bread, really! Too bad it doesn't have all the features when running against JDK 1.5 - sandos
I find VisualVM slow or unusable in some circumstances. The commercial YourKit does not have this problem, but is unfortunately not free. - Roalt
The more recent versions of Visual VM, from JDK 1.6.0_22 and later, are much improved. I would bet JDK1.7 has an even better version of it. - djangofan
4
[+173] [2009-12-07 11:59:37] crowne

Classpath wild cards since Java 6.

java -classpath ./lib/* so.Main

Instead of

java -classpath ./lib/log4j.jar:./lib/commons-codec.jar:./lib/commons-httpclient.jar:./lib/commons-collections.jar:./lib/myApp.jar so.Main

See http://java.sun.com/javase/6/docs/technotes/tools/windows/classpath.html


5
[+156] [2008-09-02 12:57:04] Georgy Bolyuba

For most people I interview for Java developer positions labeled blocks are very surprising. Here is an example:

// code goes here

getmeout:{
    for (int i = 0; i < N; ++i) {
        for (int j = i; j < N; ++j) {
            for (int k = j; k < N; ++k) {
                //do something here
                break getmeout;
            }
        }
    }
}

Who said goto in java is just a keyword? :)


(1) I'd almost hope people not know about this feature. Far preferable that they organise their code into smaller, more meaningful methods and simply use return, in most cases. There is a great furore at the moment around this language construct being added to PHP6. - Cheekysoft
(2) Well, I would rather prefer to have an option to do it several ways. For example, I saw people using System.exit(1); in Servlet and EJB code, but that does not mean that we should remove System.exit(); from the JDK, right? - Georgy Bolyuba
(1) I agree that it should be allowed in the language even if it's not used often. I can't recall a single instance when I have used it but I have seen both sides of the argument for it's use. Better to have it and not use it than need it and not have it. - martinatime
(1) I've found one instance where this was useful, do to weirdness of the flow. In the end I just redesigned the whole thing to not need it and it was simpler. I decided to abide by the "psychopath who knows where you live" rule.. - Bob Gettys
Does this need to be a block? I was under the impression it just labels the for loop. - Jack Leow
(31) Under some circumstances, within a nested loop construct, it can be useful to continue to the next iteration of an outer loop. This would be a reasonable use of this feature. - alasdairg
in case of several nested loops, yeah. But I would rather rewrite the code. - Georgy Bolyuba
I used that in stackoverflow.com/questions/288200/… First time I used it, seemed natural... :-) - PhiLho
(75) What's especially unknown to many programmers (and probably just as well) is that you can actually label and break out of ANY old block. It doesn't have to be a loop-- you can just define some arbitrary block, give it a label, and use break with it. - Neil Coffey
What a surprise I had no idea too. I like spaghetti but not in code, I'm not sure if I'd use in dangerous knowledge in the future - victor hugo
(1) Hmmm, goto. Long time no see. Inspiration becons... Eclipse, here I come! - extraneon
(27) It is not a goto at all, it can only return to a prior iteration (ie: you cannot jump forward). This is the same mechanism that occurs when an iteration returns false. Saying java has goto is like saying any language whose compiler produces a JUMP instruction has a goto statement. - Zombies
This is a great feature I use now and then to avoid nested if statemens and to shorten some iterative constructs. This is not a goto; just because you (people) don't know it doesn't mean it's wrong to use. All those "scared" should go read some book on Java. - Ondra Žižka
(2) I think the only time I would use this construct would be to translate assembly code to java on a really tight deadline. - RMorrisey
(4) So you interview based on Java trivia rather than on aptitude to solve problems and think through designs. I'll make sure I never interview with your company. :) - Javid Jamae
(2) So, you comment by stretching a point and/or making some far going generalization and/or assumptions. I'll make sure never to read your comments again. :) - Georgy Bolyuba
This can always be accomplished without the labeled block (sorry about the lack of white space): boolean breakSet = false; for (int i = 0; i < N && !breakSet; ++i) { for (int j = i; j < N && !breakSet; ++j) { for (int k = j; k < N && !breakSet; ++k) { //do something here breakSet = true; } } } - Paul Jackson
@Zombies:"It is not a goto at all, it can only return to a prior iteration (ie: you cannot jump forward)." What? Did you look at the code at all? What to you mean "cannot jump forward?" - Georgy Bolyuba
6
[+144] [2008-08-29 19:29:40] serg10

How about covariant return types which have been in place since JDK 1.5? It is pretty poorly publicised, as it is an unsexy addition, but as I understand it, is absolutely necessary for generics to work.

Essentially, the compiler now allows a subclass to narrow the return type of an overridden method to be a subclass of the original method's return type. So this is allowed:

class Souper {
    Collection<String> values() {
        ...
    }
}

class ThreadSafeSortedSub extends Souper {
    @Override
    ConcurrentSkipListSet<String> values() {
        ...
    }
}

You can call the subclass's values method and obtain a sorted thread safe Set of Strings without having to down cast to the ConcurrentSkipListSet.


Can you provide an example usage? - Allain Lalonde
(24) I use this a lot. clone() is a great example. It's supposed to return Object, which means you'd have to say e.g. (List)list.clone(). However if you declare as List clone(){...}, then the cast is unnecessary. - Jason Cohen
7
[+142] [2008-09-15 16:49:51] James A. N. Stauffer

Transfer of control in a finally block throws away any exception. The following code does not throw RuntimeException -- it is lost.

public static void doSomething() {
    try {
      //Normally you would have code that doesn't explicitly appear 
      //to throw exceptions so it would be harder to see the problem.
      throw new RuntimeException();
    } finally {
      return;
    }
  }

From http://jamesjava.blogspot.com/2006/03/dont-return-in-finally-clause.html


(7) It's nasty, but it's also kind of just a logical consequence of how finally works. The try/catch/finally flow control does what it's intended to do, but only within certain limits. Similarly, you have to be careful not to cause an exception inside a catch/finally block, or you'll also throw away the original exception. And if you do a System.exit() inside the try block, the finally block won't be called. If you break the normal flow, you break the normal flow... - Neil Coffey
Don't use finally { return; } but just finally{ code without return}. This is logical, as finally is also intended to be executed when exceptions occurred, and the only possible meaning of a return as exception handler must be to ignore the exception and - indeed - return. - extraneon
(21) This seems like more of a "gotcha" than a hidden feature, though there are ways it could be used as one, using this method wouldn't be a good idea. - davenpcj
Eclipse emits a warning if you do this. I'm with Eclipse. If you want to catch an exception... then catch an exception. - helios
That's what you pay for dirty code that returns from middle of method. But still a nice example. - Rostislav Matl
@Neil Coffey: If you cause an exception inside finally, but catch it, I presume there is no problem? - Bart van Heukelom
8
[+140] [2009-01-19 15:01:05] Cadet Pirx

Haven't seen anyone mention instanceof being implemented in such a way that checking for null is not necessary.

Instead of:

if( null != aObject && aObject instanceof String )
{
    ...
}

just use:

if( aObject instanceof String )
{
    ...
}

(9) It's a shame that this is such a little-known feature. I've seen a lot of code similar to the first block of code. - Peter Dolberg
(4) That's because Java has a special (hidden) null type that you do not see, nor can reference. - Nick Hristov
What's worse is checking for null before freeing or deleteing in C/C++. Such a fundamental concept. - Thomas Eding
9
[+134] [2008-09-09 21:10:31] Adrian Mouat

Allowing methods and constructors in enums surprised me. For example:

enum Cats {
  FELIX(2), SHEEBA(3), RUFUS(7);

  private int mAge;
  Cats(int age) {
    mAge = age;
  }
  public int getAge() {
    return mAge;
   }
}

You can even have a "constant specific class body" which allows a specific enum value to override methods.

More documentation here [1].

[1] http://java.sun.com/j2se/1.5.0/docs/guide/language/enums.html

(20) Really awesome feature actually--makes enums OO and solves a lot of initialization problems in a very clean way. - Bill K
Enums are also great for singletons because of this. - Chii
(5) Enum as singleton? Enum with only one value? - Georgy Bolyuba
(6) Georgy: Singleton is one instance of the object, not an object with one value. - dshaw
This is really handy if you want enumerators relative to a value. So in the example, perhaps you could initialise Cats with a specified age value then have FELIX(2 + age), that way, Felix's age will be relative to the instance of the Cats age. - Kieran Senior
(1) Enums are so OO that you could even add a public void setAge(int age) {this.mAge=afe} ... and it works !! - Olivier
(20) @Georgy: see also Item 3 in Joshua Bloch's Effective Java (2nd ed); "While this approach has yet to be widely adopted, a single-element enum type is the best way to implement a singleton." - Jonik
(3) Minor nitpick: mAge should be final. There's rarely a reason for non-final felds in enums. - Joachim Sauer
That almost defeats the purpose of using enums IMO. - Kelly Elton
@Jonik while this has advantages regarding initialization of the singleton instance and accessing it, this prevents you from having the singleton class extends another class (all enums implicitly extend java.lang.enum) and, though normally unneeded/unwanted to be extended. - Asaf
Sadly, enums can't extend other enums, but they can implement interfaces, which is useful sometimes. - sinuhepop
10
[+121] [2008-09-11 02:09:12] Kevin Wong

The type params for generic methods can be specified explicitly like so:

Collections.<String,Integer>emptyMap()

(10) And by god is it ugly and confusing. And irrelevant to type safety. - Chris Broadfoot
(8) I love this. It makes your code a bit more explicit and as such more clear for the poor sod who will have to maintain it in a year or two. - extraneon
(6) This is actually very useful in situations where you have declared a static generic method such as public static <T> T foo(T t). You can then make calls to Class.<Type>foo(t); - Finbarr
For some reason this doesn't seem to work with statically imported methods.. I wonder why. - oksayt
This is especially useful when using ternary ifs with a return. For example return set1.equals(set2) ? new ArrayList<String>(set1) : Collections.<String>emptyList(). It also useful for some method invocations where a simple Collections.emptyMap() would give a compile error. - Andreas Holstenson
11
[+112] [2009-02-18 21:10:20] Peter Lawrey

You can use enums to implement an interface.

public interface Room {
   public Room north();
   public Room south();
   public Room east();
   public Room west();
}

public enum Rooms implements Room {
   FIRST {
      public Room north() {
         return SECOND;
      }
   },
   SECOND {
      public Room south() {
         return FIRST;
      }
   }

   public Room north() { return null; }
   public Room south() { return null; }
   public Room east() { return null; }
   public Room west() { return null; }
}

EDIT: Years later....

I use this feature here

public enum AffinityStrategies implements AffinityStrategy {

https://github.com/peter-lawrey/Java-Thread-Affinity/blob/master/src/main/java/vanilla/java/affinity/AffinityStrategies.java

By using an interface, developers can define their own strategies. Using an enum means I can define a collection (of five) built in ones.


(12) @Arian this isn't madness. THIS. IS. JAVAAAAAAHHHH! - salezica
(1) WHAAAAAT no, I'm with Adrian. This is not Java. This is madness. I'm dying to use this. - salezica
12
[+104] [2008-11-03 17:02:46] Paul Wicks

As of Java 1.5, Java now has a much cleaner syntax for writing functions of variable arity. So, instead of just passing an array, now you can do the following

public void foo(String... bars) {
   for (String bar: bars)
      System.out.println(bar);
}

bars is automatically converted to array of the specified type. Not a huge win, but a win nonetheless.


(23) The important thing about this is when calling the method, you can write: foo("first","second","third") - Steve Armstrong
(9) so the old hello world can be rewritten; public static void main(String... args) { System.out.println("Hello World!"); } - Karussell
@Karussell Maybe, but it would seem the arguments are irrelevant :p - Kelly Elton
13
[+93] [2008-09-17 13:23:06] Chris Mazzola

My favorite: dump all thread stack traces to standard out.

windows: CTRL-Break in your java cmd/console window

unix: kill -3 PID


(15) Also ctrl-\ in Unix. Or use jstack from the JDK. - Tom Hawtin - tackline
(9) Thanks, you just taught me my keyboard has a Break key. - Amy B
(2) On windows, CTRL-BREAK only works if you have the process running in the current console window. You can use JAVA_HOME/bin/jstack.exe instead. Just provide it with the Windows process id. - Javid Jamae
I thought it was kill -SIGQUIT - Nick Hristov
@Nick, yes SIGQUIT is usually signal #3. - Chris Mazzola
14
[+89] [2008-10-27 00:12:44] Jack Leow

A couple of people have posted about instance initializers, here's a good use for it:

Map map = new HashMap() {{
    put("a key", "a value");
    put("another key", "another value");
}};

Is a quick way to initialize maps if you're just doing something quick and simple.

Or using it to create a quick swing frame prototype:

JFrame frame = new JFrame();

JPanel panel = new JPanel(); 

panel.add( new JLabel("Hey there"){{ 
    setBackground(Color.black);
    setForeground( Color.white);
}});

panel.add( new JButton("Ok"){{
    addActionListener( new ActionListener(){
        public void actionPerformed( ActionEvent ae ){
            System.out.println("Button pushed");
        }
     });
 }});


 frame.add( panel );

Of course it can be abused:

    JFrame frame = new JFrame(){{
         add( new JPanel(){{
               add( new JLabel("Hey there"){{ 
                    setBackground(Color.black);
                    setForeground( Color.white);
                }});

                add( new JButton("Ok"){{
                    addActionListener( new ActionListener(){
                        public void actionPerformed( ActionEvent ae ){
                            System.out.println("Button pushed");
                        }
                     });
                 }});
        }});
    }};

Somehow, it is a bit as if "with" keyword (functionality, actually) have been added to Java. Can be very handy, recently I grunted because init of arrays wasn't available for Collections. Thanks! - PhiLho
(15) There is one side-effect of using this, though. Anonymous objects get created, which may not be fine always. - amit
A large GUI application designed this way probably needs a bit more permgen space. Though I don't think it should take all that much space to store something which is essentially the classname and an initializer. - extraneon
Gotta say this is a better use of the static initializers than #1, but wow. Is it really that much of an advantage over naming your frame "f" and your buttons b? Readability, I'd say that even the "Short" names are better than this if not just for the "No Surprises" factor. - Bill K
(17) Although after looking at it more, I have to say I'm strangely attracted to the natural nesting this provides, even the "Abused" version. - Bill K
I like it too:) It's like JavaFX but gratis - Vlagged
(4) Yep - I quite like the 'abused' version, I think that's really very clear and readable, but perhaps that's just me. - barryred
(3) Absolutely agree, the hierarchy of the code reflecting the hierarchy of the gui is a huge improvement over a sequence of method calls. - opsb
I dislike this because it lets the application start even more slowly than Java does already. It creates a new subclass of HashMap which is completly useless. - Daniel
"referential transparency" is the reason this nesting feels nice, see wikipedia. its also vaguely lisp-y, even the "abused" version, lisp'ers seem to have high tolerance for deep composition. github.com/technomancy/leiningen/blob/master/src/leiningen/… - Dustin Getz
15
[+88] [2008-09-03 01:29:39] jodonnell

Dynamic proxies [1] (added in 1.3) allow you to define a new type at runtime that conforms to an interface. It's come in handy a surprising number of times.

[1] http://docs.oracle.com/javase/7/docs/technotes/guides/reflection/proxy.html

(10) Dynamic proxies are a great reason to choose to write a Foo interface and use that everywhere, with a default "FooImpl" class. It may seem ugly at first ("Why not just have a class called Foo?") but the benefits in terms future flexibility and mock-ability for unit tests are handy. While there are ways to also do it for non-interfaces, they typically require extra stuff like cblib. - Darien
16
[+81] [2008-10-03 21:59:37] Allain Lalonde

final initialization can be postponed.

It makes sure that even with a complex flow of logic return values are always set. It's too easy to miss a case and return null by accident. It doesn't make returning null impossible, just obvious that it's on purpose:

public Object getElementAt(int index) {
    final Object element;
    if (index == 0) {
         element = "Result 1";
    } else if (index == 1) {
         element = "Result 2";
    } else {
         element = "Result 3";
    }
    return element;
}

That's surprising. Can one fairly say, "The value of a final variable can be set once", no matter where the set occurs? - David Koelle
(29) Yes, but more strongly: "The value of a final variable must be set once" - Allain Lalonde
(6) +1 Agree, this is another valuable tool for spotting errors at compile time, and one that programmers seem shy to use for some reason. Note that because from Java 5 onwards, 'final' also has thread-safety implications, being able to set a final variable during the constructor is invaluable. - Neil Coffey
(4) Though for this specific method, I'd just use multiple returns. In fact, in most cases where this is applicable, I'd probably refactor it into a separate method and use multiple returns. - ripper234
I love this! I deleted the final keyword always because I thought it will fail. thanks! - KARASZI István
This is generally a bit of a code smell. As mentioned above it should be refactored to use guard closes(with multiple returns). If a block like this exists as only part of a method it should be extracted to a new method with multiple returns. - opsb
A few comments mentioned multiple returns -- notice that you can have the same benefit as with the final variable by omitting the return clause at the end. You would be sure all cases were handled (and appropriate values returned), because it will fail to compile otherwise. - Rob Whelan
17
[+62] [2008-08-19 16:47:35] Mo.

I think another "overlooked" feature of java is the JVM itself. It is probably the best VM available. And it supports lots of interesting and useful languages (Jython, JRuby, Scala, Groovy). All those languages can easily and seamlessly cooperate.

If you design a new language (like in the scala-case) you immediately have all the existing libraries available and your language is therefore "useful" from the very beginning.

All those languages make use of the HotSpot optimizations. The VM is very well monitor and debuggable.


(18) No. It's actually not a very good VM. It was solely designed to run JAVA. Typeless dynamic and functional languages don't work well with it. Of you want to use a VM you should use .NET/Mono. That was designed to work with EVERY language... - Hades32
(14) Actually the JVM is solely designed to run Java Bytecodes. You can compile most modern languages to Java Bytecode. About the only things Java Bytecode is lacking in is dynamic language support, pointers, and tail recursion support. - mcjabberz
(12) @Hades32: actually the .NET VM is pretty similar to the JVM. It only got support for dynamic languages relatively recently (with the DLR) and Java 7 is about to get that support as well. And the classical "EVERY language" of .NET (C#, Visual Basic.NET, ...) all have pretty much exactly the same feature set. - Joachim Sauer
(13) JVM doesn't support generics, while the .NET VM does. JVM is nowhere near the best. - Blindy
I'd rather say that BEAM (for Erlang) is the "best" VM. At least for a (large) subset of best regarding VM's. - HeMan
(1) Ok, maybe not the "best" for most definitions of "best". Nonetheless I see it as a feature of java. It has a decent JIT (Hotspot), there are many implementations, it runs on a variety of systems... - Mo.
(3) Not to discount the complaints about specific language features not directly supported by the JVM... but I tend to think stability, cross-platform consistency, and good performance are far and above the reasons the JVM gets extra points. I've been working with server-side Java for many years now on many platforms (including AS/400) and have been able to pretty much forget about it entirely -- the bugs are pretty much always in code I can fix, and it simply doesn't crash. - Rob Whelan
18
[+58] [2009-06-22 01:17:28] Ron

You can define an anonymous subclass and directly call a method on it even if it implements no interfaces.

new Object() {
  void foo(String s) {
    System.out.println(s);
  }
}.foo("Hello");

@Vuntic - It does allow you to define a simple class within the context that it is needed. - ChaosPandion
(1) @Chaos, But why? Got an actual example where it is useful? - Thorbjørn Ravn Andersen
(10) @Wouter - In that case, the method which is called on the anonymous object (start()) is not actually defined in the subclass... - Axel
Actually, this is a very useful feature if you extend a base class that does some needed setup, calls the method you write, and then does teardown. Kick the thing off by calling a method in the base class (which I probably wouldn't give the same name). There's an example use (not definition) here - AmigoNico
19
[+56] [2008-09-15 15:55:15] Bruno De Fraine

The asList [1] method in java.util.Arrays allows a nice combination of varargs, generic methods and autoboxing:

List<Integer> ints = Arrays.asList(1,2,3);
[1] http://java.sun.com/j2se/1.5.0/docs/api/java/util/Arrays.html#asList(T...)

(15) you want to wrap the returned list with a List constructor otherwise ints will be fixed size (since it is backed by the array) - KitsuneYMG
(2) The Arrays.asList has the unusual feature that you can set() elements but not add() or remove(). So I usually wrap it in a new ArrayList(...) or in a Collections.unmodifiableList(...), depending on whether I want the list modifiable or not. - Christian Semrau
20
[+53] [2008-09-19 13:02:49] Tahir Akhtar

Using this keyword for accessing fields/methods of containing class from an inner class. In below, rather contrived example, we want to use sortAscending field of container class from the anonymous inner class. Using ContainerClass.this.sortAscending instead of this.sortAscending does the trick.

import java.util.Comparator;

public class ContainerClass {
boolean sortAscending;
public Comparator createComparator(final boolean sortAscending){
    Comparator comparator = new Comparator<Integer>() {

        public int compare(Integer o1, Integer o2) {
            if (sortAscending || ContainerClass.this.sortAscending) {
                return o1 - o2;
            } else {
                return o2 - o1;
            }
        }

    };
    return comparator;
}
}

(4) That's only necessary if you've shadowed the name (in your case, with the method parameter name). If you'd called the argument something else, then you could directly access the sortAscending member variable of Container class without using 'this'. - sk.
(7) It is still useful to have a reference to the enclosing class, eg. if you need to pass it to some method or construtor. - PhiLho
Often used in Android layout development, in order to get the Context from, say, the listener of a button, with MyActivity.this. - espinchi
21
[+52] [2008-09-17 11:39:29] PhiLho

Not really a feature, but an amusing trick I discovered recently in some Web page:

class Example
{
  public static void main(String[] args)
  {
    System.out.println("Hello World!");
    http://Phi.Lho.free.fr

    System.exit(0);
  }
}

is a valid Java program (although it generates a warning). If you don't see why, see Gregory's answer! ;-) Well, syntax highlighting here also gives a hint!


(15) neat, a label with a comment :) - Thorbjørn Ravn Andersen
22
[+46] [2008-09-19 13:35:12] Das

This is not exactly "hidden features" and not very useful, but can be extremely interesting in some cases:
Class sun.misc.Unsafe - will allow you to implement direct memory management in Java (you can even write self-modifying Java code with this if you try a lot):

public class UnsafeUtil {

    public static Unsafe unsafe;
    private static long fieldOffset;
    private static UnsafeUtil instance = new UnsafeUtil();

    private Object obj;

    static {
        try {
            Field f = Unsafe.class.getDeclaredField("theUnsafe");
            f.setAccessible(true);

            unsafe = (Unsafe)f.get(null);
            fieldOffset = unsafe.objectFieldOffset(UnsafeUtil.class.getDeclaredField("obj"));
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    };
}

(20) that is a sun.* API which isn't really part of the Java language per se - DW.
There are a number of other curious methods on Unsafe like creating an object without calling a constructor, malloc/realloc/free style methods. - Peter Lawrey
I love esspecially the primitive getters and setters on memory locations, like putDouble(long address, double d). - Daniel
23
[+42] [2009-12-02 16:28:17] Devon_C_Miller

When working in Swing I like the hidden Ctrl - Shift - F1 feature.

It dumps the component tree of the current window.
(Assuming you have not bound that keystroke to something else.)


(1) Most likely your window manager has something bound to that key. Gnome doesn't bind to it, so I'm assuming you're running KDE which binds it to 'switch to desktop 13'. You can change it by going to Control panel, Regional, Keyboard Shortcuts and removing the mapping for Shift-Ctrl-F1 - Devon_C_Miller
24
[+40] [2010-02-19 05:29:42] Dolph

Every class file starts with the hex value 0xCAFEBABE to identify it as valid JVM bytecode.

( Explanation [1])

[1] http://www.artima.com/insidejvm/whyCAFEBABE.html

25
[+38] [2008-12-04 19:51:57] stili

My vote goes to java.util.concurrent with its concurrent collections and flexible executors allowing among others thread pools, scheduled tasks and coordinated tasks. The DelayQueue is my personal favorite, where elements are made available after a specified delay.

java.util.Timer and TimerTask may safely be put to rest.

Also, not exactly hidden but in a different package from the other classes related to date and time. java.util.concurrent.TimeUnit is useful when converting between nanoseconds, microseconds, milliseconds and seconds.

It reads a lot better than the usual someValue * 1000 or someValue / 1000.


Recently discovered CountDownLatch and CyclicBarrier -- so useful! - Raphael
26
[+37] [2008-08-19 01:51:22] Mark Cidade

Language-level assert keyword.


(19) The trouble with assert is that it needs to be switched on during runtime. - extraneon
(10) But if it's disabled it's like it's not there. You can add as many asserts as you want in your code and you won't have any performance penalty if they're disabled. - Ravi Wallau
(5) I believe that’s a good thing about assert: it can be turned off without penalty. - andref
the problem is, if you accidentally implemented a side effect in an assert, you've got to turn on assertion for ur program to work... - Chii
To detect if asserts are on, you can use { boolean assertsOn = false; assert assertsOn = true; if (assertsOn) { /* complex verification */ } }. This also allows to log or throw exception if state of assert is not the expected. - fernacolo
27
[+37] [2008-09-10 17:20:11] Binil Thomas

Not really part of the Java language, but the javap disassembler which comes with Sun's JDK is not widely known or used.


28
[+36] [2008-09-16 18:35:19] 18Rabbit

The addition of the for-each loop construct in 1.5. I <3 it.

// For each Object, instantiated as foo, in myCollection
for(Object foo: myCollection) {
  System.out.println(foo.toString());
}

And can be used in nested instances:

for (Suit suit : suits)
  for (Rank rank : ranks)
    sortedDeck.add(new Card(suit, rank));

The for-each construct is also applicable to arrays, where it hides the index variable rather than the iterator. The following method returns the sum of the values in an int array:

// Returns the sum of the elements of a
int sum(int[] a) {
  int result = 0;
  for (int i : a)
    result += i;
  return result;
}

Link to the Sun documentation [1]

[1] http://java.sun.com/j2se/1.5.0/docs/guide/language/foreach.html

(30) I think using i here is super-confusing, as most people expect i to be an index and not the array element. - cdmckay
So... int sum(int[] array) { int result = 0; for(int element : array) { result += element; } return result; } - Drew
(28) The only thing that drives me nuts about this is that it seems like it would be really really easy to create a keyword for accessing the loop count value, but you can't. If I want to loop over two arrays and make changes to a second based on values in the first I'm forced to use the old syntax because I have no offset into the second array. - Jherico
(6) It's a shame it doesn't also work with Enumerations, like those used in JNDI. It's back to iterators there. - extraneon
(3) @extraneon: take a look at Collections.list(Enumeration<T> e). That should help with iterating enumerations in the foreach loop. - Werner Lehmann
The only possible problem with this is that it uses the List's Iterator, and any modification to the list within the loop will throw ConcurrentModificationException. - Finbarr
@deepc Unfortunately that creates a copy of the enumeration, not a List view, so I created my own Iterable adapter that wraps around an Enumeration. - Bart van Heukelom
29
[+34] [2009-02-17 13:25:09] Rahel Lüthy

i personally discovered java.lang.Void very late -- improves code readability in conjunction with generics, e.g. Callable<Void>


(2) not quite. at some point, you need to be specific: Executors.newSingleThreadExecutor().submit(new Callable<Void>() {..}) -- you can't instantiate a new Callable<?>(), you need to specify an explicit type -- thus, it's an alternative to Callable<Object>. - Rahel Lüthy
(4) Void is more specific than Object as Void can only be null, Object can be anything. - Peter Lawrey
30
[+30] [2009-06-11 20:10:28] Peter Lawrey

Perhaps the most surprising hidden feature is the sun.misc.Unsafe class.

http://www.docjar.com/html/api/ClassLib/Common/sun/misc/Unsafe.java.html

You can;

  • Create an object without calling a constructor.
  • Throw any exception even Exception without worrying about throws clauses on methods. (There are other way to do this I know)
  • Get/set randomly accessed fields in an object without using reflection.
  • allocate/free/copy/resize a block of memory which can be long (64-bit) in size.
  • Obtain the location of fields in an object or static fields in a class.
  • independently lock and unlock an object lock. (like synchronize without a block)
  • define a class from provided byte codes. Rather than the classloader determining what the byte code should be. (You can do this with reflection as well)

BTW: Incorrect use of this class will kill the JVM. I don't know which JVMs support this class so its not portable.


(7) That's not a hidden feature of Java but a hidden feature of some specific JVM implementations. - Nat
True, though I haven't come across a JSE which doesn't have it. If any one knows one I would be interested. - Peter Lawrey
do you mean the oracle.misc.Unsafe? :) I remember when I discovered it (looking inside the sun jvm AtomicInteger implementation) and get absolutely fascinated - Mauricio
I haven't seen it called oracle.* I guess they are free to rename it one day. - Peter Lawrey
(4) I recently used it to allocate a block of 16 GB (something you can't do in Java) it took 30 seconds just to populate. I could really see main memory as the new disk. ;) - Peter Lawrey
31
[+29] [2010-01-25 09:45:51] Luigi

Here's my list.

My favourite (and scariest) hidden feature is that you can throw checked exceptions from methods that are not declaring to throw anything.

import java.rmi.RemoteException;

class Thrower {
    public static void spit(final Throwable exception) {
        class EvilThrower<T extends Throwable> {
            @SuppressWarnings("unchecked")
            private void sneakyThrow(Throwable exception) throws T {
                throw (T) exception;
            }
        }
        new EvilThrower<RuntimeException>().sneakyThrow(exception);
    }
}

public class ThrowerSample {
    public static void main( String[] args ) {
        Thrower.spit(new RemoteException("go unchecked!"));
    }
}

Also you may like to know you can throw 'null'...

public static void main(String[] args) {
     throw null;
}

Guess what this prints:

Long value = new Long(0);
System.out.println(value.equals(0));

And, guess what this returns:

public int returnSomething() {
    try {
        throw new RuntimeException("foo!");
    } finally {
        return 0;
    }
}

the above should not surprise good developers.


In Java you can declare an array in following valid ways:

String[] strings = new String[] { "foo", "bar" };
// the above is equivalent to the following:
String[] strings = { "foo", "bar" };

So following Java code is perfectly valid:

public class Foo {
    public void doSomething(String[] arg) {}

    public void example() {
        String[] strings = { "foo", "bar" };
        doSomething(strings);
    }
}

Is there any valid reason why, instead, the following code shouldn't be valid?

public class Foo {

    public void doSomething(String[] arg) {}

    public void example() {
        doSomething({ "foo", "bar" });
    }
}

I think, that the above syntax would have been a valid substitute to the varargs introduced in Java 5. And, more coherent with the previously allowed array declarations.


(2) The valid reason is that the compiler can't infer the type of the array. But good list. - CurtainDog
Isnt the doSomething({"",""}) something that will be supported with simple closures in Java 7? - Shervin Asgari
regarding your comment about "good developers" and the try/finally bad-style-puzzler-that-never-happens-in-the-wild... Well, good developers have an IDE that will warn them in realtime, even on an incomplete AST, that "such return statements (inside finally blocks) may mask exception thrown". Who are the bad developers using inferiors IDEs now? ;) - SyntaxT3rr0r
@SyntaxT3rr0r: Good developers are the ones who know more than the IDE they use can spot, since most of the logic/coding errors are not spot by IDEs. - Luigi
throw null should get you a NullPointerException at runtime. - Paŭlo Ebermann
32
[+28] [2009-12-16 23:47:36] SRG

Shutdown Hooks. [1] This allows to register a thread that will be created immediatly but started only when the JVM ends ! So it is some kind of "global jvm finalizer", and you can make useful stuff in this thread (for example shutting down java ressources like an embedded hsqldb server). This works with System.exit(), or with CTRL-C / kill -15 (but not with kill -9 on unix, of course).

Moreover it's pretty easy to set up.

            Runtime.getRuntime().addShutdownHook(new Thread() {
                  public void run() {
                      endApp();
                  }
            });;
[1] http://java.sun.com/developer/TechTips/2000/tt0711.html

(1) They're great! You can unregister them too (if you keep around a reference) so you can do nice cleanup of resources. I use them – in conjunction with Spring lifecycle callbacks, especially the destroy-method attribute – for killing off worker subprocesses. - Donal Fellows
Note that the shutdown hooks are not executed if Runtime.halt() is called. - Esko Luontola
(3) Shutdown hooks are not called in Windows if javaw is used to launch an app and Windows log off is initiated. There has to be a console window. Sigh. I was trying to use this to mark me as "out of the office" on our website and wound up having to live with the minimized console window. - Chris Mazzola
33
[+27] [2008-10-27 00:03:39] Jack Leow

The value of:

new URL("http://www.yahoo.com").equals(new URL("http://209.191.93.52"))

is true.

(From Java Puzzlers)


(48) Only if you are connected to the Internet. If it can't resolve the address, it will return false, and therefore the URL class breaks the equals() contract. Better use the URI class in java.net. - user8681
And it shouldn't, because the HTTP server can have virtual hosting and might have a different behaviour. - rds
34
[+26] [2008-09-26 03:30:29] Kevin Day

If you do a lot of JavaBean development and work with property change support, you generally wind up writing a lot of setters like this:

public void setFoo(Foo aFoo){
  Foo old = this.foo;
  this.foo = aFoo;
  changeSupport.firePropertyChange("foo", old, aFoo);
}

I recently stumbled across a blog that suggested a more terse implementation of this that makes the code a lot easier to write:

public void setFoo(Foo aFoo){
  changeSupport.firePropertyChange("foo", this.foo, this.foo = aFoo);
}

It actually simplified things to the point where I was able to adjust the setter template in Eclipse so the method gets created automatically.


(1) Is the order of execution for arguments well-defined in Java? Otherwise, this could potentially generate a mess. - Konrad Rudolph
It is well defined, but not generally well understood. This will technically work, but is clearly confusing. - Heath Borders
(7) Yes - order or execution of arguments is extremely well defined. I'm not sure that I agree that this is more confusing than having 3 lines of junk code in every single setter in every single JavaBean - much better to keep the focus on the code you want to write instead of this type of boilerplate! - Kevin Day
Coma order of execution is very well defined. Has to be left to right, always. - Bill K
I don't see why the shorter version is any easier to create automatically than the longer one. - Jason Orendorff
Jason - fair 'nough - code generation can do it either way. That is kinda the point of code generation I guess ;-) Still a lot easier to read the code with reduced boilerplate (the presence of the getter and setter at all is still a huge amount of boilerplate, but that's a discussion for another day) - Kevin Day
(5) You can use project lombok for this. - Alfred
35
[+25] [2008-08-19 02:06:42] Michael Neale

static imports to "enhance" the language, so you can do nice literal things in type safe ways:

List<String> ls = List("a", "b", "c");

(can also do with maps, arrays, sets).

http://gleichmann.wordpress.com/2008/01/13/building-your-own-literals-in-java-lists-and-arrays/

Taking it further:

List<Map<String, String>> data = List(Map( o("name", "michael"), o("sex", "male")));

It's really too bad this type of functionality isn't directly in the collections API. - Chris Mazzola
(19) this isn't part of the language; the author in the link defines the "List" method to create a list - kdgregory
(2) This is a method like: ... public static <T> List<T> List(T...elems){ return Arrays.asList( elems ); } You can also write: List<String> myList = new ArrayList<String>(Arrays.asList("One", "Two", "Three")); //as mentioned in another post - xgMz
Isn't this the Factory design pattern? Very usefull of course, especially with varargs. - extraneon
(6) static import java.util.Arrays; List<String> names = asList("jim", "john") - opsb
@opsb Also need to consider that asList returns a fixed-sized array-backed list. - Jeremy
36
[+23] [2008-08-20 11:30:49] PPS

As a starter I really appreciate the JConsole monitoring software in Java 6, it has solved a couple of problems for me already and I keep on finding new uses for it.

Apparently the JConsole was there already in Java 5 but I reckon it is improved now and at least working much more stable as of now.

JConsole in Java 5: JConsole in Java 5 [1]

JConsole in Java 6: JConsole in Java 6 [2]

And while you are at it, have a good look at the other tools in the series: Java 6 troubleshooting tools [3]

[1] http://java.sun.com/developer/technicalArticles/J2SE/jconsole.html
[2] http://java.sun.com/developer/technicalArticles/J2SE/monitoring/
[3] http://java.sun.com/javase/6/docs/technotes/tools/index.html#troubleshoot

(1) JConsole will be replaced vy VisualVM in future versions (6u10 maybe?) - Tom
(2) Sure, JConsole will be replaced or rather refined, already from 6u7 i think. But many still use the older versions of suns JVM and thus needs the JConsole. I have still not found anything supporting the theory that JVisualVM will support older versions of the JDKs. - PPS
37
[+23] [2010-07-05 18:22:40] OscarRyz

Not so hidden, but interesting.

You can have a "Hello, world" without main method ( it throws NoSuchMethodError thought )

Originally posted by RusselW on Strangest language feature [1]

public class WithoutMain {
    static {
        System.out.println("Look ma, no main!!");
        System.exit(0);
    }
}

$ java WithoutMain
Look ma, no main!!
[1] https://stackoverflow.com/questions/1995113/strangest-language-feature/3161298#3161298

(3) Add a System.exit(0); to suppress that ugly exception… - Donal Fellows
(8) This is a simple abuse of static initializations, nothing I would consider a feature of any sort... - pdinklag
38
[+22] [2008-10-06 18:14:51] Bill K

Java processing does a neat trick on variable definition if you do not use a default initializer.

{
   int x;

   if(whatever)
      x=1;

   if(x == 1)
      ...
}

This will give you an error at compile time that you have a path where X isn't properly defined. This has helped me a few times, and I've taken to considering default initialization like these:

int x=0;
String s=null;

to be a bad pattern since it blocks this helpful checking.

That said, sometimes it's difficult to get around--I have had to go back and edit in the =null when it made sense as a default, but I never put it in on the first pass any more.


(3) +1 Agreed-- for some reason some people find it "confusing" not to supply an initial value for a variable, as though they think the compiler is secretly going to pick a random number or something. But as you rightly say, it's a valuable tool to spot certain errors at compile-time. - Neil Coffey
That's because in the C universe, uninitialized pointers were the bane of existence - though if I remember correctly, in the C++ universe, pointers were automatically initialized to null if allocated on the stack. - Chris K
Yeah, that's why it's worth pointing out that it's no longer really a good idea and in fact somewhat counter-productive. - Bill K
(5) Use final wherever possible for additional checks. - Wouter Lievens
39
[+21] [2010-06-28 04:36:04] Jason Wang

This is not really a hidden feature but it did give me a big surprise when I saw this compiled fine:

public int aMethod(){
    http://www.google.com
    return 1;
}

the reason why it compiles is that the line http://www.google.com the "http:" part is treated by the compiler as a label and the rest of the line is a comment.

So, if you want to write some bizzare code (or obfuscated code), just put alot of http addresses there. ;-)


but more than a year old. See this answer from "David Plumpton" at May 12 '09: stackoverflow.com/questions/15496/hidden-features-of-java/… (and he only got 2 upvotes...) - user85421
(13) This is a duplicate answer - Shervin Asgari
(7) ... and it works with at most one http address per method, as labels are to be unique. - Paŭlo Ebermann
40
[+20] [2008-09-28 15:45:22] oxbow_lakes

You can declare a class in a method:

public Foo foo(String in) {
    class FooFormat extends Format {
        public Object parse(String s, ParsePosition pp) { // parse stuff }
    }
    return (Foo) new FooFormat().parse(in);

}

You could have also just go new Format() {, instead of declaring the FooFormat class - Pyrolistical
(4) Anonymous classes are overrated. Try debugging one sometime, or supporting one in the field, and you'll see what I mean. Once you lose line numbers in a release build, they're very hard to track. - TREE
(5) and they are called local classes :) java.sun.com/docs/books/jls/second_edition/html/… - Özgür
I prefer to tame anonymous classes by having them call back into the main object to do their work; the anonymous class is just an adapter and so is easy to get right. - Donal Fellows
@Donal - I use this with UI code a lot. It's worth saying that this design is bad from the perspective of refactoring though. You could extract a "top-level" class and find that it's logic was implemented by another class entirely! - oxbow_lakes
@oxbow: I don't entirely get your point. The only thing in my inner class is a call to a (usually non-public) method on the outer class. While yes, in theory it could be quite surprising that this is going on, it's pretty easy to see in practice as it is just a call with no exception handling. - Donal Fellows
41
[+19] [2008-09-15 15:50:33] Andrew

It took them long enough to add support for this,

System Tray [1]

[1] http://java.sun.com/docs/books/tutorial/uiswing/misc/systemtray.html

42
[+17] [2008-08-19 02:03:53] Mo.

I really like the rewritten Threading API from Java 1.6. Callables are great. They are basically threads with a return value.


When compared to the older stuff is simple - Allain Lalonde
Basically there are ExecutorServices, to which you can submit Callables. When you submit a Callable to an ExecutorService, you get back a Future, which has a blocking call to get the result of the Callable (or you can ask it if there is a result yet, non-blocking). - Adam Jaskiewicz
An ExecutorService is some way of running Callables (and Runnables). It might be a single background thread, it might be backed by a thread pool, it might even run the tasks sequentially in the current thread. Depends on the implementation. - Adam Jaskiewicz
There's also a CompletionService that can have Callables submitted to it, and the results queue up for consumption as they finish. - Adam Jaskiewicz
43
[+17] [2008-09-10 20:18:12] randomrareposts

Self-bound generics:

class SelfBounded<T extends SelfBounded<T>> {
}

http://www.artima.com/weblogs/viewpost.jsp?thread=136394


(1) see also the cope's crtp: artima.com/weblogs/viewpost.jsp?thread=133275 - Ray Tayek
44
[+16] [2009-02-17 12:56:31] youri

I like the static import of methods.

For example create the following util class:

package package.name;

public class util {

     private static void doStuff1(){
        //the end
     }

     private static String doStuff2(){
        return "the end";
     }

}

Then use it like this.

import static package.name.util.*;

public class main{

     public static void main(String[] args){
          doStuff1(); // wee no more typing util.doStuff1()
          System.out.print(doStuff2()); // or util.doStuff2()
     }

}

Static Imports [1] works with any class, even Math...

import static java.lang.Math.*;
import static java.lang.System.out;
public class HelloWorld {
    public static void main(String[] args) {
        out.println("Hello World!");
        out.println("Considering a circle with a diameter of 5 cm, it has:");
        out.println("A circumference of " + (PI * 5) + "cm");
        out.println("And an area of " + (PI * pow(5,2)) + "sq. cm");
    }
}
[1] http://en.wikipedia.org/wiki/Static_import

(1) please fix 'S' letter case in both doStuffX methods in your sample. This could be confusing. - Archer
45
[+16] [2009-02-17 13:22:17] chillitom

List.subList returns a view on the original list

A documented but little known feature of lists. This allows you to work with parts of a list with changes mirrored in the original list.

List subList(int fromIndex, int toIndex)

"This method eliminates the need for explicit range operations (of the sort that commonly exist for arrays). Any operation that expects a list can be used as a range operation by passing a subList view instead of a whole list. For example, the following idiom removes a range of elements from a list:

       list.subList(from, to).clear();

Similar idioms may be constructed for indexOf and lastIndexOf, and all of the algorithms in the Collections class can be applied to a subList."


(3) Be careful with subList, it will hold the whole underlying list in memory, even if you only store a reference to the sub-list. It is very different from, say, a "tail" operation in a functional language. - lexicalscope
And, depending on implementation, some operations may be slower on the sublist than they would be on the complete list. - Paŭlo Ebermann
When people see list.subList(from, to).clear() they go wow this is so cool! Except that in other libraries, it's simply list.RemoveRange(from, to) which is so much neater, direct, and usable. - Pacerier
46
[+16] [2009-11-26 19:03:03] Jonathan Locke

Oh, I almost forgot this little gem. Try this on any running java process:

jmap -histo:live PID

You will get a histogram of live heap objects in the given VM. Invaluable as a quick way to figure certain kinds of memory leaks. Another technique I use to prevent them is to create and use size-bounded subclasses of all the collections classes. This causes quick failures in out-of-control collections that are easy to identify.


47
[+16] [2009-11-27 08:39:36] kcak11

A feature with which you can display splash screens for your Java Console Based Applications.

Use the command line tool java or javaw with the option -splash

eg:

java -splash:C:\myfolder\myimage.png -classpath myjarfile.jar com.my.package.MyClass

the content of C:\myfolder\myimage.png will be displayed at the center of your screen, whenever you execute the class "com.my.package.MyClass"


That's really kind of hidden... can't find the option in the documentation for the java (java.exe) command. (but it's on the help message or javadoc of SplashScreen) - user85421
48
[+15] [2008-08-20 10:07:43] serg10

Not really a feature, but it makes me chuckle that goto is a reserved word that does nothing except prompting javac to poke you in the eye. Just to remind you that you are in OO-land now.


(10) Is there some relationship between Object Oriented programming and not using "goto"? - Adrian Pronk
49
[+15] [2008-11-12 16:59:39] user24081

Javadoc - when written properly (not always the case with some developers unfortunately), it gives you a clear, coherent description of what code is supposed to do, as opposed to what it actually does. It can then be turned into a nice browsable set of HTML documentation. If you use continuous integration etc it can be generated regularly so all developers can see the latest updates.


50
[+15] [2009-02-04 17:19:12] drscroogemcduck

with static imports you can do cool stuff like:

List<String> myList = list("foo", "bar");
Set<String> mySet = set("foo", "bar");
Map<String, String> myMap = map(v("foo", "2"), v("bar", "3"));

(4) you could even do this with generics. Google Collections has nice utils for that. - Tim Büthe
51
[+14] [2009-01-01 05:19:38] Romain Guy

The strictfp keyword. (I never saw it used in a real application though :)

You can get the class for primitive types by using the following notation: int.class, float.class, etc. Very useful when doing reflection.

Final arrays can be used to "return" values from anonymous inner classes (warning, useless example below):

final boolean[] result = new boolean[1];
SwingUtilities.invokeAndWait(new Runnable() {
  public void run() { result[0] = true; }
});

using a final array to return from an anon inner class like that is probably not recommended good programming practice... - Chii
Romain Guy? Like, the Romain Guy? ...Anyway, +1 for int.class. I thought Integer.TYPE was the only way. - Michael Myers
More than useless. The code immediately following this is likely to be executed before the EDT callback. Therefore it wont see the true value. - Tom Hawtin - tackline
(2) I've used strictfp myself. This was for a program where potential movement of double s between the registers (80-bits) and RAM (64-bits) could cause problems - Chinmay Kanchi
(1) For invokeAndWait this is more useful than for invokeLater, really. - Paŭlo Ebermann
52
[+14] [2010-06-21 23:04:28] OscarRyz

You can define and invoke methods on anonymous inner classes.

Well they're not that hidden, but very few people know they can be used to define a new method in a class and invoke it like this:

(new Object() {
    public String someMethod(){ 
        return "some value";
    }
}).someMethod();

Probably is not very common because it not very useful either, you can call the method it only when you define it ( or via reflection )


Looks a little bit like the JavaScript module pattern ;) - Johannes Wachter
53
[+13] [2008-09-03 00:33:17] yalestar

I was aware that Java 6 included scripting support, but I just recently discovered jrunscript [1], which can interpret and run JavaScript (and, one presumes, other scripting languages such as Groovy) interactively, sort of like the Python shell or irb in Ruby

[1] http://java.sun.com/javase/6/docs/technotes/tools/share/jrunscript.html

54
[+13] [2010-06-30 08:06:02] st0le

The C-Style printf() :)

System.out.printf("%d %f %.4f", 3,Math.E,Math.E);

Output: 3 2.718282 2.7183

Binary Search (and it's return value)

int[] q = new int[] { 1,3,4,5};
int position = Arrays.binarySearch(q, 2);

Similar to C#, if '2' is not found in the array, it returns a negative value but if you take the 1's Complement of the returned value you actually get the position where '2' can be inserted.

In the above example, position = -2, ~position = 1 which is the position where 2 should be inserted...it also lets you find the "closest" match in the array.

I thinks its pretty nifty... :)


printf is not hidden, neither is the working of binarySearch. - user85421
No feature mentioned in the previous answers are exactly "hidden". Most of them are just "relatively unknown" to the common java programmer. Atleast that's what i thought the question was... - st0le
55
[+12] [2008-08-29 19:17:46] John Meagher

It's not exactly hidden, but reflection is incredibly useful and powerful. It is great to use a simple Class.forName("...").newInstance() where the class type is configurable. It's easy to write this sort of factory implementation.


(1) I use reflection all the time to do things like <T> T[] filterItems(T[]) which you can then call with items = filterItems(items); The method definition is a bit uglier, but it really makes client code easier to read. - Marcus Downing
It is powerful because it allows you to break every static guarantee and invariant Java, javac and interfaces give you. Use with extreme care. - Raphael
56
[+12] [2008-09-04 15:55:03] Matt Cummings

I know this was added in release 1.5 but the new enum type is a great feature. Not having to use the old "int enum pattern" has greatly helped a bunch of my code. Check out JLS 8.9 [1] for the sweet gravy on your potatoes!

[1] http://java.sun.com/docs/books/jls/third_edition/html/classes.html#8.9

Most "old school" Java guys never bother to start using this feature, but I agree it's great. - Allain Lalonde
57
[+12] [2009-06-04 09:06:47] AaronG

Part feature, part bother: Java's String handling to make it 'appear' a native Type (use of operators on them, +, +=)

Being able to write:

String s = "A";
s += " String"; // so s == "A String"

is very convenient, but is simply syntactic sugar for (ie gets compiled to):

String s = new String("A");
s = new StringBuffer(s).append(" String").toString();

ergo an Object instantiation and 2 method invocations for a simple concatenation. Imagine Building a long String inside a loop in this manner!? AND all of StringBuffer's methods are declared synchronized. Thankfully in (I think) Java 5 they introduced StringBuilder which is identical to StringBuffer without the syncronization.

A loop such as:

String s = "";
for (int i = 0 ; i < 1000 ; ++i)
  s += " " + i; // Really an Object instantiation & 3 method invocations!

can (should) be rewritten in your code as:

StringBuilder buf = new StringBuilder(); // Empty buffer
for (int i = 0 ; i < 1000 ; ++i)
  buf.append(' ').append(i); // Cut out the object instantiation & reduce to 2 method invocations
String s = buf.toString();

and will run approximately 80+% faster than the original loop! (up to 180% on some benchmarks I have run)


(2) The literal "A" really is a java.lang.String, though its backing character array is allocated in a different way to dynamically-created strings. - Donal Fellows
I knew this and have tested. These happens because creating and destroying objects is one of most expensive things in any Object Oriented language. I've heard once... - John John Pichler
(1) Current compilers would use StringBuilder instead of StringBuffer there for string concatenation. - Paŭlo Ebermann
58
[+11] [2008-09-06 09:07:16] dmeister

final for instance variables:

Really useful for multi-threading code and it makes it a lot easier to argue about the instance state and correctness. Haven't seen it a lot in industry context and often not thought in java classes.


static {something;}:

Used to initialize static members (also I prefer a static method to do it (because it has a name). Not thought.


Yeah, a static method will also allow you to deal nicely with exceptions but when you use the static block you have no choice but to catch (and not do any appropriate action). - Graham Edgecombe
59
[+11] [2009-07-28 03:21:04] Peter Recore

I just (re)learned today that $ is a legal name for a method or variable in Java. Combined with static imports it can make for some slightly more readable code, depending on your view of readable:

http://garbagecollected.org/2008/04/06/dollarmaps/


(1) The $ symbol is also used for distinguishing inner classes from their enclosing classes in most compilers. - Dave Jarvis
(7) You can also use £ and € signs in variable names. As well as any UNICODE letters æ, ø, å etc. - Andrey Adamovich
60
[+10] [2008-09-16 20:01:59] Michael Myers

"const" is a keyword, but you can't use it.

int const = 1;   // "not a statement"
const int i = 1; // "illegal start of expression"

I guess the compiler writers thought it might be used in the future and they'd better keep it reserved.


(1) Not exactly a "feature", but definitely "hidden". - Michael Myers
Not just a non-feature, an anti-feature! (I also didn't mention that goto is the same--reserved but unimplemented). - Michael Myers
It is reserved for the compiler to create better error messages. - Paŭlo Ebermann
goto is also a keyword, you cannot use. ;) - Peter Lawrey
(1) @Peter Lawrey: I know, but it had already been posted. - Michael Myers
61
[+10] [2009-11-04 15:00:01] Lastnico

Use StringBuilder instead of StringBuffer when you don't need synchronized management included in StringBuilder. It will increase the performance of your application.

Improvements for Java 7 would be even better than any hidden Java features:

Don't use those infinite <> syntax at instanciation:

Map<String, List<String>> anagrams = new HashMap<String, List<String>>();

// Can now be replaced with this:

Map<String, List<String>> anagrams = new HashMap<>();

Use String in switch, instead of old-C int:

String s = "something";
switch(s) {
 case "quux":
    processQuux(s);
    // fall-through

  case "foo":
  case "bar":
    processFooOrBar(s);
    break;

  case "baz":
     processBaz(s);
    // fall-through

  default:
    processDefault(s);
    break;
}
  • Automatic Resource Management Link [3]

This old code:

static void copy(String src, String dest) throws IOException {
    InputStream in = new FileInputStream(src);
    try {
        OutputStream out = new FileOutputStream(dest);
        try {
            byte[] buf = new byte[8 * 1024];
            int n;
            while ((n = in.read(buf)) >= 0)
                out.write(buf, 0, n);
        } finally {
            out.close();
        }
    } finally {
        in.close();
    }
}

can now be replaced by this much simpler code:

static void copy(String src, String dest) throws IOException {
    try (InputStream in = new FileInputStream(src);
            OutputStream out = new FileOutputStream(dest)) {
        byte[] buf = new byte[8192];
        int n;
        while ((n = in.read(buf)) >= 0)
            out.write(buf, 0, n);
    }
}
[1] http://mail.openjdk.java.net/pipermail/coin-dev/2009-February/000009.html
[2] http://mail.openjdk.java.net/pipermail/coin-dev/2009-February/000001.html
[3] http://mail.openjdk.java.net/pipermail/coin-dev/2009-February/000011.html

(4) Do you mean StringBuilder instead of StringWriter? The APIs for StringBuffer and StringBuilder are the same however using StringWriter would require some code changes. - pjp
(2) He actually meant StringBuilder which is not thread-safe but faster. StringBuffer is thread safe, but slower. Should be used only if you need thread safety while building your string buffer. - Archer
62
[+9] [2008-09-24 19:37:07] Alan Moore

How about Properties files in your choice of encodings? Used to be, when you loaded your Properties, you provided an InputStream and the load() method decoded it as ISO-8859-1. You could actually store the file in some other encoding, but you had to use a disgusting hack like this after loading to properly decode the data:

String realProp = new String(prop.getBytes("ISO-8859-1"), "UTF-8");

But, as of JDK 1.6, there's a load() method that takes a Reader instead of an InputStream, which means you can use the correct encoding from the beginning (there's also a store() method that takes a Writer). This seems like a pretty big deal to me, but it appears to have been snuck into the JDK with no fanfare at all. I only stumbled upon it a few weeks ago, and a quick Google search turned up just one passing mention of it.


Don't do your hack, please - it messes up all \uXXXX escape sequences. Better use native2ascii to convert the file after editing and before deploying, or use the reader variant of the load() method. - Paŭlo Ebermann
63
[+9] [2008-09-27 01:11:17] OscarRyz

Something that really surprised me was the custom serialization mechanism.

While these methods are private!!, they are "mysteriously" called by the JVM during object serialization.

private void writeObject(ObjectOutputStream out) throws IOException;
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException;

This way you can create your own custom serialization to make it more "whatever" (safe, fast, rare, easy etc. )

This is something that really should be considering if a lot of information has to be passed through nodes. The serialization mechanism may be changed to send the half of data. There are many times when the bottlenecks are not in the platform, but in the amount of that sent trough the wire, may save you thousands of dlls in hardware.

Here is an article. http://java.sun.com/developer/technicalArticles/Programming/serialization/


This is also useful for custom serialization for objects with non-Serializable members. - user8681
64
[+9] [2009-06-22 02:46:05] Dave Jarvis

An optimization trick that makes your code easier to maintain and less susceptible to a concurrency bug.

public class Slow {
  /** Loop counter; initialized to 0. */
  private long i;

  public static void main( String args[] ) {
    Slow slow = new Slow();

    slow.run();
  }

  private void run() {
    while( i++ < 10000000000L )
      ;
  }
}

$ time java Slow
real 0m15.397s
$ time java Slow
real 0m20.012s
$ time java Slow
real 0m18.645s

Average: 18.018s

public class Fast {
  /** Loop counter; initialized to 0. */
  private long i;

  public static void main( String args[] ) {
    Fast fast = new Fast();

    fast.run();
  }

  private void run() {
    long i = getI();

    while( i++ < 10000000000L )
      ;

    setI( i );
  }

  private long setI( long i ) {
    this.i = i;
  }

  private long getI() {
    return this.i;
  }
}

$ time java Fast
real 0m12.003s
$ time java Fast
real 0m9.840s
$ time java Fast
real 0m9.686s

Average: 10.509s

It requires more bytecodes to reference a class-scope variable than a method-scope variable. The addition of a method call prior to the critical loop adds little overhead (and the call might be inlined by the compiler anyway).

Another advantage to this technique (always using accessors) is that it eliminates a potential bug in the Slow class. If a second thread were to continually reset the value of i to 0 (by calling slow.setI( 0 ), for example), the Slow class could never end its loop. Calling the accessor and using a local variable eliminates that possibility.

Tested using J2SE 1.6.0_13 on Linux 2.6.27-14.


(1) but Fast is not the same as Slow: the value of member "Fast.i" is NOT changed by/after the loop. If you call the run() method a second time, Slow will be much faster (increments "i" only once) and Fast will be as slows before since "Fast.i" is still zero. - user85421
You are correct, Carlos. To make Fast and Slow have the same behaviour (in a single-threaded environment), the instance variable "i" would have to be updated at the end of the "run" method, which would not significantly impact performance. - Dave Jarvis
also got a "strange" result using System.currentTimeMillis() around the call to calculate the runtime: slow is faster than fast (slow=40.6s, fast=42.9s) for 1.6.0_13-b03 on WindowsXP - user85421
Carlos: Try four runs for both classes without any potentially CPU-intensive programs running (e.g., virus checker, system update, browser). Also, throw out the first run in both test volleys. That Fast is slower than Slow by ~2 seconds leads me to believe something interfered with the runs. (That is, it should not take 2 seconds to get and set a variable via its accessor.) - Dave Jarvis
(2) "Premature optimization" is a phrase used to describe a situation where a programmer lets performance considerations affect the design of a piece of code. This can result in a design that is not as clean as it could have been or code that is incorrect, because the code is complicated by the optimization and the programmer is distracted by optimizing. [ref: en.wikipedia.org/wiki/Optimization_%28computer_science%29] - jdigital
@jdigital: I do not consider it premature. When methods are synchronized, it protects against the following problem: stackoverflow.com/questions/2458217/… - Dave Jarvis
65
[+9] [2010-01-09 20:04:01] stacker

Identifiers can contain foreign language chars like umlauts:

instead of writing:

String title="";

someone could write:

String Überschrift="";

(1) and you can access it like \u00dcberschrift = "OK"; - user85421
(8) Not good style in my opinion. You know what I mean if you ever had to work with some code with comments and identifiers in a language you do not understand. Code should not be localized. - Werner Lehmann
The problem is not so much that in any real-size project there will be developers speaking different languages... The problem is that in any real size project there shall be a mix of Windows and Unx (including OS X) machines and a mix of different IDEs using different setups. Combine that with the fact that *.java text files have no metadata describing their file encodings nor good specs (the specs allow any character encoding) and you've got your recipe for disasters. Java programmers using non-ASCII chars inside String of in identifiers deserve to be shot to death. - SyntaxT3rr0r
(1) non-ASCII Strings should be externalized and build scripts and/or pre-commit verifiers should be configured to fail immediately upon detecting such clueless non-sense. Our Ant build scripts here will fail and put any developer trying to do that on the wall of shame. - SyntaxT3rr0r
66
[+9] [2010-06-09 09:07:06] mbenturk

I can add Scanner object. It is the best for parsing.

String input = "1 fish 2 fish red fish blue fish";
Scanner s = new Scanner(input).useDelimiter("\\s*fish\\s*");
System.out.println(s.nextInt());
System.out.println(s.nextInt());
System.out.println(s.next());
System.out.println(s.next());
s.close();

(4) In my opinion, this is not a hidden feature. The Scanner is a library. - Shervin Asgari
67
[+8] [2008-09-29 11:09:52] pimeja

Annotation Processing API from Java 6 looks very perspective for code generation and static code verification.


68
[+8] [2009-06-03 14:32:26] Huxi

People are sometimes a bit surprised when they realize that it's possible to call private methods and access/change private fields using reflection...

Consider the following class:

public class Foo {
    private int bar;

    public Foo() {
        setBar(17);
    }

    private void setBar(int bar) {
        this.bar=bar;
    }

    public int getBar() {
        return bar;
    }

    public String toString() {
        return "Foo[bar="+bar+"]";
    }
}

Executing this program...

import java.lang.reflect.*;

public class AccessibleExample {
    public static void main(String[] args)
        throws NoSuchMethodException,IllegalAccessException, InvocationTargetException, NoSuchFieldException {
        Foo foo=new Foo();
        System.out.println(foo);

        Method method=Foo.class.getDeclaredMethod("setBar", int.class);
        method.setAccessible(true);
        method.invoke(foo, 42);

        System.out.println(foo);
        Field field=Foo.class.getDeclaredField("bar");
        field.setAccessible(true);
        field.set(foo, 23);
        System.out.println(foo);
    }
}

...will yield the following output:

Foo[bar=17]
Foo[bar=42]
Foo[bar=23]

The setAccessible call can be forbidden by the Security manager, though. - Paŭlo Ebermann
69
[+8] [2009-08-20 11:45:23] mdakin

Most people does not know they can clone an array.

int[] arr = {1, 2, 3};
int[] arr2 = arr.clone();

You can call clone on any Object. You just need to be careful that the Object implements a deep clone. - Finbarr
(8) @Finbarr: Quite the reverse. It does a shallow clone; the inner objects just get another reference to them. The “simplest” way to deep clone is to serialize and deserialize, or to actually understand what you're making a copy of. - Donal Fellows
@Finbar: one can't call clone on any Object, only on objects from classes which made this method public, or are from the current class. - Paŭlo Ebermann
70
[+7] [2008-09-15 16:19:57] Bill Michell

JVisualVM from the bin directory in the JDK distribution. Monitoring and even profiling any java application, even one you didn't launch with any special parameters. Only in recent versions of the Java 6SE JDK.


If you're using Spring to tool up your annotated JMX beans to work with jconsole and jvisualvm, you need to manually start the management interface rather than relying on the default VM-created one. If you don't, you'll run into problems with the presence of multiple clashing “singletons” and your JMX beans will neatly end up in the wrong one… - Donal Fellows
71
[+7] [2008-09-17 17:37:59] mpresley

The power you can have over the garbage collector and how it manages object collection is very powerful, especially for long-running and time-sensitive applications. It starts with weak, soft, and phantom references in the java.lang.ref package. Take a look at those, especially for building caches (there is a java.util.WeakHashMap already). Now dig a little deeper into the ReferenceQueue and you'll start having even more control. Finally grab the docs on the garbage collector itself and you'll be able to control how often it runs, sizes of different collection areas, and the types of algorithms used (for Java 5 see http://java.sun.com/docs/hotspot/gc5.0/gc_tuning_5.html).


WeakHashMap is not suitable for building caches. - Bombe
72
[+7] [2008-10-23 14:18:16] Dr. Hans-Peter Störr

You can access final local variables and parameters in initialization blocks and methods of local classes. Consider this:

    final String foo = "42";
    new Thread() {
        public void run() {
             dowhatever(foo);
        }
    }.start();

A bit like a closure, isn't it?


I knew that you can't acces non-finals, but I was surprised that you can access finals. - Dr. Hans-Peter Störr
73
[+7] [2009-02-04 16:52:03] Sarel Botha

You can build a string sprintf-style using String.format().

String w = "world";
String s = String.format("Hello %s %d", w, 3);

You can of course also use special specifiers to modify the output.

More here: http://java.sun.com/j2se/1.5.0/docs/api/java/util/Formatter.html#syntax


74
[+7] [2009-11-26 18:43:48] Jonathan Locke

Actually, what I love about Java is how few hidden tricks there are. It's a very obvious language. So much so that after 15 years, almost every one I can think of is already listed on these few pages.

Perhaps most people know that Collections.synchronizedList() adds synchronization to a list. What you can't know unless you read the documentation is that you can safely iterate on the elements of that list by synchronizing on the list object itself.

CopyOnWriteArrayList might be unknown to some, and Future represents an interesting way to abstract multithreaded result access.

You can attach to VMs (local or remote), get information on GC activity, memory use, file descriptors and even object sizes through the various management, agent and attach APIs.

Although TimeUnit is perhaps better than long, I prefer Wicket's Duration class.


75
[+6] [2008-09-08 13:24:57] warsze

Joshua Bloch's new Effective Java [1] is a good resource.

[1] https://rads.stackoverflow.com/amzn/click/com/0321356683

Great book, but it doesn't really deal so much with hidden features. - James McMahon
76
[+6] [2008-09-15 16:08:02] Bruno De Fraine

Some control-flow tricks, finally around a return statement:

int getCount() { 
  try { return 1; }
  finally { System.out.println("Bye!"); }
}

The rules for definite assignment [1] will check that a final variable is always assigned through a simple control-flow analysis:

final int foo;
if(...)
  foo = 1;
else
  throw new Exception();
foo+1;
[1] http://java.sun.com/docs/books/jls/third_edition/html/defAssign.html

77
[+6] [2009-05-12 03:47:42] David Plumpton

Source code URLs. E.g. here is some legal java source code:

http://google.com

(Yes, it was in Java Puzzlers. I laughed...)


78
[+6] [2010-01-22 22:33:07] Karussell

Didn't read about this

Integer a = 1;
Integer b = 1;
Integer c = new Integer(1);
Integer d = new Integer(1);

Integer e = 128;
Integer f = 128;

assertTrue (a == b);   // again: this is true!
assertFalse(e == f); // again: this is false!
assertFalse(c == d);   // again: this is false!

read more about this by searching java's pool of integer (internal 'cache' from -128 to 127 for autoboxing) or look into Integer.valueOf


(3) The exact limit is implementation dependent (has only some minimum size), so in some VMs the second test could be true, too. - Paŭlo Ebermann
Is it true to say that the third test will be false regardless of the VM ? - Pacerier
@Pacerier to be honest. not sure. but it worked at the time I was posting this ... just do not depend on the == operator ... - Karussell
So, they use the pointer to store small integer values, is that it? - Hejazzman
This is specified by the Java Language Specification for the range [-127,127]. As for the other integers, I'm not sure - Miguel Ping
79
[+5] [2008-09-08 16:38:47] Dan Dyer
[1] http://www.unix.com.ua/orelly/java-ent/jnut/ch03_11.htm
[2] http://virtualinfinity.net/wordpress/java/esoteric-java-features/2007/01/09/6/

80
[+5] [2008-09-26 13:06:23] Martin Spamer

String Parameterised Class Factory.

Class.forName( className ).newInstance();

Load a resource (property file, xml, xslt, image etc) from deployment jar file.

this.getClass().getClassLoader().getResourceAsStream( ... ) ;

81
[+5] [2008-11-26 19:04:22] David Koelle

Instances of the same class can access private members of other instances:

class Thing {
  private int x;

  public int addThings(Thing t2) {
    return this.x + t2.x;  // Can access t2's private value!
  }
}

It was only until very recently that I learned this, and someone had to point it out to me in a comment left on my blog. - moffdub
(1) It's surprising if you have exposure to an OO language other than C++. - Pete Kirkham
(3) It's awful. Don't do it. It's not because I'm human that another human has the right to look into my bowels ;-) - cadrian
(6) But how would you do a proper hash/equals implementation if you cant access its innards? - Chii
(1) it is exactly the same logic that allows a method to access a private instance variable... private classes are part of the implementation, thus there should be no restrictions on the access between inner classes and the parent, the parent and inner classes, and inner classes to other inner classes. - TofuBeer
82
[+5] [2009-02-04 15:58:41] Sarel Botha

The next-generation Java plugin found in Java 1.6 Update 10 and later has some very neat features:

  • Pass java_arguments parameter to pass arguments to the JVM that is created. This allows you to control the amount of memory given to the applet.
  • Create separate class loaders or even separate JVM's for each applet.
  • Specify the JVM version to use.
  • Install partial Java kernels in cases where you only need a subset of the full Java libraries' functionality.
  • Better Vista support.
  • Support (experimental) to drag an applet out of the browser and have it keep running when you navigate away.

Many other things that are documented here: http://jdk6.dev.java.net/plugin2/

More from this release here: http://jdk6.dev.java.net/6u10ea.html


83
[+5] [2009-02-22 07:22:36] paulmurray

Intersection types allow you to (kinda sorta) do enums that have an inheritance hierarchy. You can't inherit implementation, but you can delegate it to a helper class.

enum Foo1 implements Bar {}
enum Foo2 implements Bar {}

class HelperClass {
   static <T extends Enum<T> & Bar> void fooBar(T the enum) {}
}

This is useful when you have a number of different enums that implement some sort of pattern. For instance, a number of pairs of enums that have a parent-child relationship.

enum PrimaryColor {Red, Green, Blue;}
enum PastelColor {Pink, HotPink, Rockmelon, SkyBlue, BabyBlue;}

enum TransportMedium {Land, Sea, Air;}
enum Vehicle {Car, Truck, BigBoat, LittleBoat, JetFighter, HotAirBaloon;}

You can write generic methods that say "Ok, given an enum value thats a parent of some other enum values, what percentage of all the possible child enums of the child type have this particular parent value as their parent?", and have it all typesafe and done without casting. (eg: that "Sea" is 33% of all possible vehicles, and "Green" 20% of all possible Pastels).

The code look like this. It's pretty nasty, but there are ways to make it better. Note in particuar that the "leaf" classes themselves are quite neat - the generic classes have declarations that are horribly ugly, but you only write them onece. Once the generic classes are there, then using them is easy.

import java.util.EnumSet;

import javax.swing.JComponent;

public class zz extends JComponent {

    public static void main(String[] args) {
        System.out.println(PrimaryColor.Green + " " + ParentUtil.pctOf(PrimaryColor.Green) + "%");
        System.out.println(TransportMedium.Air + " " + ParentUtil.pctOf(TransportMedium.Air) + "%");
    }


}

class ParentUtil {
    private ParentUtil(){}
    static <P extends Enum<P> & Parent<P, C>, C extends Enum<C> & Child<P, C>> //
    float pctOf(P parent) {
        return (float) parent.getChildren().size() / //
                (float) EnumSet.allOf(parent.getChildClass()).size() //
                * 100f;
    }
    public static <P extends Enum<P> & Parent<P, C>, C extends Enum<C> & Child<P, C>> //
    EnumSet<C> loadChildrenOf(P p) {
        EnumSet<C> cc = EnumSet.noneOf(p.getChildClass());
        for(C c: EnumSet.allOf(p.getChildClass())) {
            if(c.getParent() == p) {
                cc.add(c);
            }
        }
        return cc;
    }
}

interface Parent<P extends Enum<P> & Parent<P, C>, C extends Enum<C> & Child<P, C>> {
    Class<C> getChildClass();

    EnumSet<C> getChildren();
}

interface Child<P extends Enum<P> & Parent<P, C>, C extends Enum<C> & Child<P, C>> {
    Class<P> getParentClass();

    P getParent();
}

enum PrimaryColor implements Parent<PrimaryColor, PastelColor> {
    Red, Green, Blue;

    private EnumSet<PastelColor>    children;

    public Class<PastelColor> getChildClass() {
        return PastelColor.class;
    }

    public EnumSet<PastelColor> getChildren() {
        if(children == null) children=ParentUtil.loadChildrenOf(this);
        return children;
    }
}

enum PastelColor implements Child<PrimaryColor, PastelColor> {
    Pink(PrimaryColor.Red), HotPink(PrimaryColor.Red), //
    Rockmelon(PrimaryColor.Green), //
    SkyBlue(PrimaryColor.Blue), BabyBlue(PrimaryColor.Blue);

    final PrimaryColor  parent;

    private PastelColor(PrimaryColor parent) {
        this.parent = parent;
    }

    public Class<PrimaryColor> getParentClass() {
        return PrimaryColor.class;
    }

    public PrimaryColor getParent() {
        return parent;
    }
}

enum TransportMedium implements Parent<TransportMedium, Vehicle> {
    Land, Sea, Air;

    private EnumSet<Vehicle>    children;

    public Class<Vehicle> getChildClass() {
        return Vehicle.class;
    }

    public EnumSet<Vehicle> getChildren() {
        if(children == null) children=ParentUtil.loadChildrenOf(this);
        return children;
    }
}

enum Vehicle implements Child<TransportMedium, Vehicle> {
    Car(TransportMedium.Land), Truck(TransportMedium.Land), //
    BigBoat(TransportMedium.Sea), LittleBoat(TransportMedium.Sea), //
    JetFighter(TransportMedium.Air), HotAirBaloon(TransportMedium.Air);

    private final TransportMedium   parent;

    private Vehicle(TransportMedium parent) {
        this.parent = parent;
    }

    public Class<TransportMedium> getParentClass() {
        return TransportMedium.class;
    }

    public TransportMedium getParent() {
        return parent;
    }
}

84
[+5] [2009-04-20 03:26:55] David Plumpton

Read "Java Puzzlers" by Joshua Bloch and you will be both enlightened and horrified.


85
[+5] [2009-08-14 09:35:40] Ivan Tarasov

It has already been mentioned [1] that a final array can be used to pass a variable out of the anonymous inner classes.

Another, arguably better and less ugly approach though is to use AtomicReference (or AtomicBoolean/AtomicInteger/…) class from java.util.concurrent.atomic package.

One of the benefits in doing so is that these classes also provide such methods as compareAndSet, which may be useful if you're creating several threads which can modify the same variable.


Another useful related pattern:

final AtomicBoolean dataMsgReceived = new AtomicBoolean(false);
final AtomicReference<Message> message = new AtomicReference<Message>();
withMessageHandler(new MessageHandler() {
    public void handleMessage(Message msg) {
         if (msg.isData()) {
             synchronized (dataMsgReceived) {
                 message.set(msg);
                 dataMsgReceived.set(true);
                 dataMsgReceived.notifyAll();
             }
         }
    }
}, new Interruptible() {
    public void run() throws InterruptedException {
        synchronized (dataMsgReceived) {
            while (!dataMsgReceived.get()) {
                dataMsgReceived.wait();
            }
        }
    }
});

In this particular example we could have simply waited on message for it to become non-null, however null may often be a valid value and then you need to use a separate flag to finish the wait.

waitMessageHandler(…) above is yet another useful pattern: it sets up a handler somewhere, then starts executing the Interruptible which may throw an exception, and then removes the handler in the finally block, like so:

private final AtomicReference<MessageHandler> messageHandler = new AtomicReference<MessageHandler>();
public void withMessageHandler(MessageHandler handler, Interruptible logic) throws InterruptedException {
    synchronized (messageHandler) {
        try {
            messageHandler.set(handler);
            logic.run();
        } finally {
            messageHandler.set(null);
        }
    }
}

Here I assume that the messageHandler's (if it's not null) handleMessage(…) method is called by another thread when a message is received. messageHandler must not be simply of MessageHandler type: that way you will synchronize on a changing variable, which is clearly a bug.

Of course, it doesn't need to be InterruptedException, it could be something like IOException, or whatever makes sense in a particular piece of code.

[1] https://stackoverflow.com/questions/15496/hidden-features-of-java/404567#404567

86
[+5] [2009-08-20 10:06:32] sibnick

Comma & array. It is legal syntax: String s[] = {
"123" ,
"234" ,
};


I had the trailing comma break on a certain version of javac, 1.6.0_13 or 17 I think - gtrak
87
[+5] [2010-01-14 11:59:43] nos

Java 6 (from Sun) comes with an embedded JavaScrip interpreter.

http://java.sun.com/javase/6/docs/technotes/guides/scripting/programmer_guide/index.html#jsengine


Usage example: java2s.com/Code/Java/JDK-6/… - Paul Lysak
88
[+4] [2008-08-29 19:36:48] Brad Barker

Functors are pretty cool. They are pretty close to a function pointer, which everyone is usually quick to say is impossible in Java.

Functors in Java [1]

[1] http://chaoticjava.com/posts/functors-in-java-and-beyond/

(7) Not impossible, merely impossibly verbose. - Pete Kirkham
Isnt this a feature of opps than java specific?? - Ravisha
89
[+4] [2008-11-20 20:19:01] Dan Vinton

SwingWorker [1] for easily managing user interface callbacks from background threads.

[1] http://en.wikipedia.org/wiki/SwingWorker

90
[+4] [2008-12-03 06:21:29] Joe

Apparently with some debug builds there is an option which dumps the native (JIT) assembly code from HotSpot: http://weblogs.java.net/blog/kohsuke/archive/2008/03/deep_dive_into.html

Unfortunately I wasn't able to find the build via the link in that post, if anyone can find a more precise URL, I'd love to play with it.


(2) download.java.net/jdk6/binaries and then for whatever platform you use the last link (with debug in the name). I loooooove that feature! - akuhn
91
[+4] [2009-11-26 17:57:23] user219590

You can switch(this) inside method definitions of enum classes. Made me shout "whut!" loudly when I discovered that this actually works.


Yes, switch works with enum expressions generally, not only inside of enum classes. - Paŭlo Ebermann
92
[+4] [2010-03-03 15:17:48] Yanamon

You can add runtime checks of generic types using a Class<T> object, this comes in handy when a class is being created in a configuration file somewhere and there is no way to add a compile time check for the generic type of the class. You dont want the class to blow up at runtime if the app happens to be configured wrong and you dont want all you classes riddled with instance of checks.

public interface SomeInterface {
  void doSomething(Object o);
}
public abstract class RuntimeCheckingTemplate<T> {
  private Class<T> clazz;
  protected RuntimeChecking(Class<T> clazz) {
    this.clazz = clazz;
  }

  public void doSomething(Object o) {
    if (clazz.isInstance(o)) {
      doSomethingWithGeneric(clazz.cast(o));
    } else {
      // log it, do something by default, throw an exception, etc.
    }
  }

  protected abstract void doSomethingWithGeneric(T t);
}

public class ClassThatWorksWithStrings extends RuntimeCheckingTemplate<String> {
  public ClassThatWorksWithStrings() {
     super(String.class);
  }

  protected abstract void doSomethingWithGeneric(T t) {
    // Do something with the generic and know that a runtime exception won't occur 
    // because of a wrong type
  }
}

93
[+3] [2008-09-20 04:14:30] biojae

Since no one else has said it yet (I Think) my favorite feature is Auto boxing!

public class Example
{
    public static void main(String[] Args)
    {
         int a = 5;
         Integer b = a; // Box!
         System.out.println("A : " + a);
         System.out.println("B : " + b);
    }
}

(5) I think the question is about hidden features, not favourite features. I'm guessing autoboxing is pretty well known to anyone who uses 1.5 or later. - Andrew Swan
@Trick Using valueOf explicitly makes no difference as autoboxing compiles to an invocation of valueOf. This is memory-efficient compared to invoking the Integer or Long constructor for small values, because valueOf uses a cache of small values. - Christian Semrau
(1) autoboxing is one of the most abused features. Not that it is a major issue, in fact, you'll never notice it, but you will find thousands of cases like boolean b = Boolean.valueOf(someString) in all projects imaginable. - MeBigFatGuy
94
[+3] [2008-10-04 21:05:34] Claes Jakobsson

Some years ago when I had to do Java (1.4.x) I wanted an eval() method and Suns javac is (was?) written in Java so it was just to link tools.jar and use that with some glue-code around it.


95
[+2] [2010-01-25 07:20:06] finnw

You can override a method and have the superclass constructor call it (this may come as a surprise to C++ programmers.)

Example [1]

[1] https://stackoverflow.com/questions/2129647/exception-vs-throwable-in-java/2129655#2129655

(2) This can lead to a lot of problems. Consider this: class B extends class A and overrides method doSomething(), which is called by A's constructor. Now constructors are called in base -> derived order, but A's constructor calls B's doSomething(). Is B initialized? - ivant
96
[+1] [2009-01-29 17:44:43] grayger

I enjoyed

  1. javadoc [1]'s taglet and doclet that enable us to customize javadoc output.
  2. JDK tools [2]: jstat, jstack etc.
[1] http://java.sun.com/javase/6/docs/technotes/guides/javadoc/
[2] http://java.sun.com/javase/6/docs/technotes/tools/

97
[0] [2009-06-22 15:10:26] Nat

Java Bean property accessor methods do not have to start with "get" and "set".

Even Josh Bloch gets this wrong in Effective Java.


(6) Well, of course they don't it's more of a code convention. Many frameworks/apis rely on reflection to access your properties, so not using get(is)/set is just asking for troubles. - serg
(5) That's proving my point. The use of get/set prefixes is taken from the Java Beans API and is just the default naming convention, not mandatory. But authors of poorly designed frameworks/APIs seem not to know this. They hard-code a naming convention that classes must use to work with their framework (and then have the cheek to say that their framework supports POJOs; mandating a naming convention, by definition, makes their framework not support POJOs). - Nat
98
[-3] [2010-04-09 12:15:46] user312723

I was surprised when I first noticed the Ternary-Operator which equals a simple if-then-else statement:

minVal = (a < b) ? a : b;

(13) IMHO it's neither hidden nor suprising, most languages i know have it (C, C++, C#, PHP, Perl, Javascript, ...) - user253984
I know that by now, but a few weeks ago I did not think of such an operator. It is probably because I am not too expierienced, but my mind was somewhat blown :D - user312723
(1) I agree with @dbermerlin. This is NOT a hidden feature. It very common. - Shervin Asgari
99
[-8] [2009-12-03 07:08:29] fastcodejava

Surprises me that an interface can extend multiple interfaces but class can extend only one class.


(1) Not really. There's never any issues as to "which superclass implementation should be called", since there are no implementations. - WhyNotHugo
How you would extend 2 classes that has same named method? What method will be included into final implementation? - Archer
@archer multiple inheritance is actually possible. In that case you point out, we can simply reject it or employ one of the name conflict resolution techniques. - Pacerier
100