I've heard Java people defend boilerplate code countless times. Just take getters and setters. People will tell you "the IDE generates them anyway". What you can't do within the bounds of the language is to loop over all accessors and replace them with something else that might call the original versions. A technique that's used frequently in Rails for instance.
To do that in Java you need code generators (probably built into IDEs), frameworks that supplant the entire object creation mechanism to hook in proxies, or byte code manipulation. All of these techniques are orders of magnitude more complex and error prone than dynamic metaprogramming or lisp macros. And despite all the complexity some things just can't be done. There is no way to call a Java method (using regular method call syntax) that the compiler doesn't see. So even if you know the method will be there because some other code will have created it by the time it is invoked, you still need to put a useless method stub somewhere in the source code.
To do that in Java you need code generators (probably built into IDEs), frameworks that supplant the entire object creation mechanism to hook in proxies, or byte code manipulation. All of these techniques are orders of magnitude more complex and error prone than dynamic metaprogramming or lisp macros. And despite all the complexity some things just can't be done. There is no way to call a Java method (using regular method call syntax) that the compiler doesn't see. So even if you know the method will be there because some other code will have created it by the time it is invoked, you still need to put a useless method stub somewhere in the source code.