295
votes

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

2
  • 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. Commented Nov 5, 2009 at 18:10
  • 1
    You (/someone) should probabbly sum up the answers neatly in the question body like the C# question. Commented Dec 10, 2009 at 19:34

100 Answers 100

30
votes

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.

Sign up to request clarification or add additional context in comments.

5 Comments

That's not a hidden feature of Java but a hidden feature of some specific JVM implementations.
True, though I haven't come across a JSE which doesn't have it. If any one knows one I would be interested.
do you mean the oracle.misc.Unsafe? :) I remember when I discovered it (looking inside the sun jvm AtomicInteger implementation) and get absolutely fascinated
I haven't seen it called oracle.* I guess they are free to rename it one day.
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. ;)
29
votes

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.

5 Comments

The valid reason is that the compiler can't infer the type of the array. But good list.
Isnt the doSomething({"",""}) something that will be supported with simple closures in Java 7?
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: 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.
throw null should get you a NullPointerException at runtime.
28
votes

Shutdown Hooks. 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(); } });; 

3 Comments

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.
Note that the shutdown hooks are not executed if Runtime.halt() is called.
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.
27
votes

The value of:

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

is true.

(From Java Puzzlers)

2 Comments

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.
And it shouldn't, because the HTTP server can have virtual hosting and might have a different behaviour.
26
votes

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.

7 Comments

Is the order of execution for arguments well-defined in Java? Otherwise, this could potentially generate a mess.
It is well defined, but not generally well understood. This will technically work, but is clearly confusing.
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!
Coma order of execution is very well defined. Has to be left to right, always.
You can use project lombok for this.
|
25
votes

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"))); 

6 Comments

It's really too bad this type of functionality isn't directly in the collections API.
this isn't part of the language; the author in the link defines the "List" method to create a list
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
Isn't this the Factory design pattern? Very usefull of course, especially with varargs.
static import java.util.Arrays; List<String> names = asList("jim", "john")
|
23
votes

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

JConsole in Java 6: JConsole in Java 6

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

2 Comments

JConsole will be replaced vy VisualVM in future versions (6u10 maybe?)
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.
23
votes

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

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

2 Comments

Add a System.exit(0); to suppress that ugly exception…
This is a simple abuse of static initializations, nothing I would consider a feature of any sort...
22
votes

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.

4 Comments

+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.
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.
Yeah, that's why it's worth pointing out that it's no longer really a good idea and in fact somewhat counter-productive.
Use final wherever possible for additional checks.
21
votes

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. ;-)

3 Comments

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...)
This is a duplicate answer
... and it works with at most one http address per method, as labels are to be unique.
20
votes

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); } 

6 Comments

You could have also just go new Format() {, instead of declaring the FooFormat class
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.
and they are called local classes :) java.sun.com/docs/books/jls/second_edition/html/…
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 - 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!
|
19
votes

It took them long enough to add support for this,

System Tray

Comments

17
votes

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

4 Comments

When compared to the older stuff is simple
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).
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.
There's also a CompletionService that can have Callables submitted to it, and the results queue up for consumption as they finish.
17
votes

Self-bound generics:

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

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

1 Comment

16
votes

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 Comments

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.
And, depending on implementation, some operations may be slower on the sublist than they would be on the complete list.
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.
16
votes

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.

Comments

16
votes

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"

1 Comment

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)
16
votes

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 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 Comment

please fix 'S' letter case in both doStuffX methods in your sample. This could be confusing.
15
votes

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.

2 Comments

Is there some relationship between Object Oriented programming and not using "goto"?
15
votes

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.

Comments

15
votes

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")); 

1 Comment

you could even do this with generics. Google Collections has nice utils for that.
14
votes

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 )

1 Comment

Looks a little bit like the JavaScript module pattern ;)
14
votes

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; } }); 

5 Comments

using a final array to return from an anon inner class like that is probably not recommended good programming practice...
Romain Guy? Like, the Romain Guy? ...Anyway, +1 for int.class. I thought Integer.TYPE was the only way.
More than useless. The code immediately following this is likely to be executed before the EDT callback. Therefore it wont see the true value.
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
For invokeAndWait this is more useful than for invokeLater, really.
13
votes

I was aware that Java 6 included scripting support, but I just recently discovered jrunscript, 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

Comments

13
votes

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... :)

2 Comments

printf is not hidden, neither is the working of binarySearch.
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...
12
votes

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.

2 Comments

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.
It is powerful because it allows you to break every static guarantee and invariant Java, javac and interfaces give you. Use with extreme care.
12
votes

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 for the sweet gravy on your potatoes!

1 Comment

Most "old school" Java guys never bother to start using this feature, but I agree it's great.
12
votes

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)

3 Comments

The literal "A" really is a java.lang.String, though its backing character array is allocated in a different way to dynamically-created strings.
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...
Current compilers would use StringBuilder instead of StringBuffer there for string concatenation.
11
votes

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.

1 Comment

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).
11
votes

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/

2 Comments

The $ symbol is also used for distinguishing inner classes from their enclosing classes in most compilers.
You can also use £ and € signs in variable names. As well as any UNICODE letters æ, ø, å etc.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.