3

I want to create such object in Java that will contain some "dispatcher" function like Object getAttr(String name) that will receive all attribute access attempts - so, if I'll do System.out.print(myObj.hello), actual code will be translated to something like System.out.print(myObj.getAttr('hello')), and if I will do myObj.hello = 123, it should execute as myObj.setAttr('hello', 123). Please, note that I should be able to use ANY attribute name, I don't know list of possible names in advance.

So, in this case, is it ever possible?

UPD#1: I'm writing new language for JVM (somehow (J|P)ython-like, so let's call it Jython) with very tight Java integration intented. One of wanted design features is ability to seamlessly access Jython object attributes from Java code just by typing jythonObject.some_attribute. So here is the deal.

Closed: Using AOP via AspectJ seems to be the only possible solution for this, so thank you all for help, and especially Thomas for the most extended answer :)

toriningen
  • 7,196
  • 3
  • 46
  • 68

5 Answers5

3

It is not possible using pure Java, except via:

Bytecode Manipulation

For example using AspectJ.

Annotation Processor

Using a custom annotation processor, which actually is a kind of bytecode manipulation as well. Projekt Lombok is doing something like this.

Synthetic Accessor Method

That is, if the code is anyway using a synthetic accessor method (in which case you could in theory create a proxy):

public class Test {
    public static void main(String... args) {
        TestClass t = new TestClass();
        // this is actually calling a synthetic accessor method
        t.hello = "x";
    }
    static class TestClass {
        private String hello;
    }
}
Thomas Mueller
  • 48,905
  • 14
  • 116
  • 132
  • Annotations are fine and powerful, but unfortunately they are inapplicable in my case. AspectJ however may help, but I'm not sure how will it affect other code (I'm interested in making things "out of the box" as much as possible). And I didn't really get Synthetic Accessor Method, could you please explain? Does Java automatically generate setter for field when it's directly accessed in allowed scope? – toriningen Jun 07 '11 at 00:16
  • @modchan - yes javac generates setters and getter for fields such as the above, and uses them when accessing the field (`t.hello = ...`; also for read access). Eclipse (if configured correctly) will actually warn you about that, because it's a tiny bit slower than direct field access. Those methods are only generated and used in a small subset of cases (if the field is private or protected I believe), so it might not work for you. – Thomas Mueller Jun 07 '11 at 10:49
2

If we stay strictly on OOP grounds, your fields should not be accessible from the outside at all. All field access should be done through get/set methods.

And intercepting methods of an interface is possible via dynamic proxies. (Important note: you can't do it with classes, only interfaces.)

If this doesn't suit your needs (although unless you're writing a third party tool, it probably should) then there's only the messy way, aspect-oriented programming or straightforward bytecode hacking.

It would help if we knew what you need to do this for though.

biziclop
  • 48,926
  • 12
  • 77
  • 104
  • Concerning dynamic proxies - as far as I understand, if I don't own an interface of object (e.g. if it's "foreign" and is fully dynamic), dynamic proxies will not help me much? – toriningen Jun 07 '11 at 00:12
  • @modchan Your assumption about dynamic proxies is correct. Looking at the updated question I'd vote for manual bytecode manipulation as the solution. – biziclop Jun 07 '11 at 12:45
1

You'll have to use AspectJ (http://www.eclipse.org/aspectj/) or another AOP library.

Jaksa
  • 2,007
  • 2
  • 12
  • 7
0

Groovy language has tools for AOP, and tiny library already exists for handling your case: https://github.com/nanonull/bean-trace

Dmitriy L
  • 120
  • 2
  • 9
0

Check out Aspect-Oriented Programming (AOP).

Hosam Aly
  • 41,555
  • 36
  • 141
  • 182