Hacking Into A Java Class

Official Java Docs may call it Anonymous Inner Classes or name it with some other heavy-weight formal jargon, but I would like to call it hacking into a Java class because with this technique you can inject your code into an existing class method.

For example, if you have a message queue and you want to make sure that you email the message items when at least 20 items have been accumulated in the queue, you can try this technique:

Queue<String> queue = new LinkedList<String>() {
			@Override
			public boolean add(String e) {
                            // save the result from original functionality
			    boolean result = super.add(e);
				
                            // inject our functionality
			    if ( this.size() >= 20 ) {					
					String str;
					StringBuilder grandString = new StringBuilder();					
					while ( ( str = this.poll() ) != null ) {
						grandString.append(str)
							.append("\n");
					}
					
					// log or grandString or email to a recipient
					System.out.println(grandString);
				} 
                            // return original result				
			    return result;
			}
		};

Cool, isn’t it?

Umar Ashfaq

Umar Ashfaq is a full-stack web developer. His core strengths are Java (Spring, Hibernate stack) and JavaScript (both client-side and server-side). Follow him on twitter @umarashfaq87

More Posts

Follow Me:
TwitterFacebookLinkedIn

No related posts.

8 Comments

  • 1
    Matthias Langer
    May 30, 2013 - 1:40 pm | Permalink

    I would be careful with “hacking into” Java collection implementations like this. These classes are not designed for inheritance, so I guess you, or the people using your “enhanced” objects, will run into nasty surprises sooner or later. Note also that your “Queue” does not behave like a Queue at all, as it is simply emptied after 20 elements have been added and thereby violates the contract specified by the Collection interface [2].

    The technique you are describing above might in fact be useful, but only with classes designed for it (ThreadLocal [3] for an example).

    [1]: http://en.wikipedia.org/wiki/Decorator_pattern
    [2]: http://docs.oracle.com/javase/6/docs/api/java/util/Collection.html#add%28E%29
    [3]: http://docs.oracle.com/javase/6/docs/api/java/lang/ThreadLocal.html

    • 2
      Umar Ashfaq
      May 30, 2013 - 2:07 pm | Permalink

      Thanks for comment, Matthias. My point is only code injection into existing methods without going into trouble of creating a new class, extending it from the parent class and overriding one or more methods to enhance their functionality. I know it is more or less the same, but with some lesser code.

      I am curios why would you use this technique with ThreadLocal and not with a Collection class? And how do you know if a class is designed for this technique while others are not?

      *EDIT*

      Whenever you extend a class and override a method, you are changing it’s intended behavior. Does it mean that Collection classes shouldn’t extended? Please help me understand.

  • 3
    Matthias Langer
    May 31, 2013 - 11:55 am | Permalink

    Hello Umar, I currently only have the worst internet connection you can imagine, but I will answer your questions as best as I can in a few days when I’m home again.

  • 4
    Umar Ashfaq
    May 31, 2013 - 8:16 pm | Permalink

    Sure Matthias, I am eager to learn your thoughts. Thanks!

  • 5
    June 3, 2013 - 5:15 pm | Permalink

    Hello Umar!

    I’ve tried to answer you questions in a blog post:
    http://mlangc.wordpress.com/2013/06/03/be-careful-when-hacking-into-a-java-class/

    Please take this as constructive criticism!

    Best,
    Matthias

  • 6
    Umar Ashfaq
    June 4, 2013 - 2:19 am | Permalink

    Thanks for detailed explanation, Matthias. And yes your points seem to make sense. But I guess if we override the add() method of LinkedList without tweaking it’s behavior, and inject some kind of read-only functionality (such as printing added item to console as a basic example), then it should be fine, right?

  • 7
    June 5, 2013 - 1:42 am | Permalink

    Well, by injecting only read-only functionality you will most likely preserve the “is-a” relationship between the parent class the the anonymous class. But the second problem still remains: LinkedList is not designed for inheritance, as, for example, you can’t know for sure if add(…) is implemented using addAll(…), addAll(…) implemented using add(…), or if add(…) and addAll(…) are implemented independently. The LinkedList implementation I looked at implements add(…) and addAll(…) independently while the HashSet implementation I looked at implements addAll(…) using add(…). So, to stick to your example, you might still get duplicate log messages, or miss others completely.

    I think what you really want is a List decorator (see [1] for example). It is more typing of course (using [2] might help), but what you get in the end will be a reusable piece of code that works with any List implementation.

    [1]: http://en.wikipedia.org/wiki/Decorator_pattern
    [2]: http://commons.apache.org/proper/commons-collections/javadocs/api-release/org/apache/commons/collections/list/AbstractListDecorator.html

  • Leave a Reply

    Your email address will not be published. Required fields are marked *

    *

    Wrap your code in [sourcecode language="java"][/sourcecode] tag (you can replace "java" with language you are using).