Actually some obfuscators are pretty advanced. For instance, in java
byte code there is a goto. But the java language itself does not
have a goto. So some obfuscators take advantage of this and put
gotos all over the place to drive the code in all different
directions. The effect this has is that even if the code can be
decompiled, it ends up looking completely different structurally then
the way it was originally written. Other obfuscation tricks do
include method renaming and messing up string literals (since they
appear in whole inside the byte code).
However, there are some risks to using obfuscators that one must
certainly consider. For instance, if you are writing a jar that
other people can use, then you don't want to scramble the method
names since it will make it impossible for outside code to use those
methods. Also, the goto technique will lower the efficiency of code
and should not be used in critical code, which is unfortunately most
often the code you want to protect. Also obfuscators will mess up
tools such as AspectJ or JDO that work directly with the byte code to
add extra functionality to your code.
Bottom line is, you have to carefully weigh the different techniques
of obfuscation and see if there's any you can safely use. For a lot
of applications, obfuscation just isn't going to help much. But you
can at least take comfort in the fact that your local variable names
are automatically obfuscated by the compiler and all the comments are
stripped out.