0

I need to create anonymous inner types that are expensive to build and need to acces a final variable in it. The problem is that I need to create many of them with the only difference that the used final variable is different (object itself and type).

Is it possible to do this in a more reusable manner?

A simple example:

final Object aNeededParameter = "test";
Object expensiveToBuild = new ExpensiveInnerType() {
    public void doSomething() {
         aNeededParameter.toString();
    }
});

I need instances of expensiveToBuild for different Objects at the same time, for example 1L, new Date(), "another similar usecase"

The basic idea is to create proxies for different serialized instances of concrete classes at runtime, that deserialize this objects on first usage. I made a working example (link at the bottom) but the proxy creation is very expensive.

There is a ProxyFactory that needs a MethodHandler to create a Proxy object via bytecode-enhancement. The MethodHandler defines a Method

invoke(Object self, Method realMethod, Method proxyMethod, Object[] args) throws Throwable

In my case this method needs access to a byte[] containing the serialized object the proxy is build for. So I have to create a new MethodHandler and build/compile a new Proxy object for each object I want a proxy for.

The invoke method is called automatically before every method call on the original object and simply checks if that object initialized and deserializes it if not. After that it invokes the called method on the original object.

If you want to see the concrete usecase look here:

Lazy deserializationproxy for java

3 Answers3

4

Just don't make it anonymous. The point of anonymous classes is when you don't expect to reuse them. Pass the necessary final variable to the class via a constructor.

Other option is to allow doSomething to take the parameter instead of the constructor, if you want the anonymous class to be instantiated once. You will still need to make it not anonymous and it will need to be owned by the parent class but this allows you to only use one object. Whether this is good design depends on the specifics.

djechlin
  • 59,258
  • 35
  • 162
  • 290
  • And pass the necessary final variable to the class via a constructor. – FThompson Nov 28 '12 at 20:19
  • And use generics to handle different types – Aubin Nov 28 '12 at 20:21
  • I "think" creating an instance of the anonymous inner class is the expensive part he is concerned about, not the actual definition of the class. –  Nov 28 '12 at 20:23
  • Indeed I simply made it not anonymous, (need some sleep I guess?) but the creationprocess is still too expensive. This instance is needed by a ProxyFactory that builds a Proxy object using bytecodeenhancement (javassist) and every builded proxy only differs on this single variable used in the former anonymous object. –  Nov 28 '12 at 21:36
  • @mklemenz - then just make the doSomething method take the object that changes and insantiate one object per 2nd paragraph? does that not work? – djechlin Nov 28 '12 at 21:53
  • @djechlin sorry, but I don't think I really understand you. one per 2nd paragraph? –  Nov 28 '12 at 22:14
  • @mklemenz "per" as in "as explained in" – djechlin Nov 28 '12 at 22:18
  • @djechlin sorry about that. I cannot change the definition of that function. it is defined in a third party interface. The method caller should not know about this function called behind the scenes (it is a Proxy object). He things he calls for example toString on a Bean. The object behind (the Bean) is not instanciated at this time, the caller does not know about it. Then the proxy handles the deserialization behind the scenes, calls toString on the real object and returns that string to caller. The creation of that Proxy is very expensive with only 1 variable differing. –  Nov 28 '12 at 22:38
  • Wrap the expensive object in a lightweight / cheap object that takes expensive object and `aNeededParameter` as constructor arguments. – djechlin Nov 28 '12 at 22:40
  • I made it not anonymous like you said. Then I found an obvious possibility to change the handler (the changing part) at runtime. (sleep helped a lot) The only Problem was if I cannot directly modify the ProxyObject, because all Objects of same Class use the same, but it need to be unique for each instance. I tried to clone the Proxy before setting the new handler, but it does not implement clonable. The ProxyFactory allows to implement classes specified at runtime, so my ProxyObject implements Clonable now and I call clone via reflection. Results: ~3,271,000ns vs ~18,500ns after warmup Thanks! –  Nov 29 '12 at 05:19
1

Make the object the anonymous inner class references an instance of some wrapper class for the object that changes (e.g. one of the instance variables of the wrapper class is of type object, and just change that variable as needed).

1

do you mean

final Object[] param = { null };

Foo foo = new Foo() 
    void invoke() 
        use param[0]

param[0] = objA;
foo.invoke();

param[0] = objB;
foo.invoke();
irreputable
  • 44,725
  • 9
  • 65
  • 93
  • @mklemenz Given this information I think you need to provide more information in your original question. –  Nov 28 '12 at 20:32