In java, a reference variable contains object reference which is some kind of wrapper over raw addr or pointer or some sort of mapping and during dereferencing this mapping is used to navigate to the object’s location in heap.
To see stored value, we tried 2 examples: Print it and Access without printing
Printing:
This is basic, just printing using println method to see exact stored value (we can use some logging framework also), here the high level code calls toString indirectly somewhere due to this we are not able to just print the reference variable’s exact stored value, i.e. now obj.toString()
is being called and our intention is to print(obj)
alone. And this is reason which most give as to why you can’t print actual value stored in reference variable.
Accessing:
Here we are not printing reference variable value but we try to access just the reference variable (without any explicit dereferencing) like string concat using + operator:
String str = new String("Test String ");
String newStr = str + new Student();
If we check newStr:
Test String com.ex.objref.Student@3b07d329
Here also we are almost sure that toString is called during concat, so we checked in decompiled bytecode and found out that concat op + is replaced with this method:
18: invokedynamic #7, 0 // InvokeDynamic #0:makeConcatWithConstants:(Ljava/lang/String;Student;)Ljava/lang/String;
BootstrapMethods:
0: #26 REF_invokeStatic java/lang/invoke/StringConcatFactory.makeConcatWithConstants:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;
And that inside is calling toString().
In this example where we are just accessing the reference variable, for this specific example we can see that now the toString is called from low level code and that is not allowing only the reference value to be accessed.
I want to know:
- Is java abstracting or restricting to not see/print/access the actual value of reference variable by virtue of toString() as seen in above 2 usecases?
- Or there are some other checks which are placed in jvm or in bytecode instructions which ensure that if we are accessing/ printing any reference variable without any dereferencing on it, don’t allow it and instead do some sort of dereferencing on it?
- And some example of those checks like what all does jvm check like it checks if the value is primitive or non-primitive?
PS: I don’t want to understand everything like how it works but atleast
if I am thinking it in right direction, I just want to know
what
all does jvm do to
restrict/abstract the reference variable value and not how
it does.