1

I am currently using ASM to intercept all attempts to mutate field values in a target application this is working as expected as ASM allows you to prepend or append instructions to method or constructor code segments.

However, it occurred to me that its a fairly common developer paradigm to initialize fields outside the scope of a Method or Constructor for example:

public class Example{ //--VARIABLE INITIALIZATION OUTSIDE METHOD OR CONSTRUCTOR SCOPE --- private String aString = "A String Value"; //zero argument constructor public Example(){ } //all other methods. } 

My question is: how would one approach the task of Intercepting field access made in this way i.e out side the context of a Method or Constructor?

2 Answers 2

2

This looks like it's outside the constructor in the source code, but in fact in the bytecode the initializers are all part of the constructor(s) - they get "moved" into the constructor by the compiler. The initializers are placed after the implicit or explicit super() call but before the rest of the constructor's code. In particular this means that if you have a situation like this:

class Super { protected Super() { doSomeStuff(); } protected abstract void doSomeStuff(); } class Sub extends Super { private int number = 1; public Sub() { super(); System.out.println("in Sub(): " + number); } protected doSomeStuff() { System.out.println("in doSomeStuff(): " + number); } } 

then new Sub(); would print

in doSomeStuff(): 0 in Sub(): 1 

as the in doSomeStuff print happens before the Sub field initializers have run.

Sign up to request clarification or add additional context in comments.

1 Comment

Your additional insight into how this works in the context of a subclass is also very much appreciated. Thank you.
1

All code is inside methods (constructors and static initializers are also methods).

You have initial values for fields, which you can see in the Field declaration, but the compiler doesn't seem to use these much.

private String aString = "A String Value"; //zero argument constructor public Example(){ } 

is the same as

private String aString; //zero argument constructor public Example(){ super(); aString = "A String Value"; } 

2 Comments

For some reason I assumed this was being done by some hidden initializer block. Thanks for clearing that up - you are, of course, correct.
In ASM the constructors are called <init>(...)V and the static initialiser block is called <clinit>()V

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.