based on this...
For example: there's a getter method that returns a field of a class but I want to change the return value to something I want instead of the expected value
you may be confusing JNI with reflection. If say you want to invoke some method in a dll somewhere inside your own jvm, you'll have to use JNI to envelope java runtime calls around some c++ code.
If you, on the other hand, want to intercept fields and/or methods in your own runtime, you'll have to use the reflection api.
The reflection API applies to pretty much everything in java, including methods, fields, annotations, etc. https://docs.oracle.com/javase/tutorial/reflect/
e.g.
class someClass{
String myMethod(){
return "somethingSomething";
}
}
may be called during runtime with
new someClass().myMethod() // returns somethingSomething
... and using the reflection API with
someClass importantObject = new someClass();
someClass.getClass().getMethod("myMethod").invoke(importantObject);
in which case, evidently you can intercept the return value of that method and change it how you want... but doing things this way is not the best of ideas.
e.g.
String vader = String.class.cast(someClass.getClass().getMethod("myMethod").invoke(importantObject)).concat("Darkside");
System.out.println(vader);
should yield (if i didn't mess up the code)
somethingSomethingDarkside
which is something you've technically mutated and behaves differently as opposed to whatever the initial method should return.
but be advised... this is kinda dumb.
reflection is usually kind of a last resort type of deal as it can completely screw up jvms.... so I'd advise caution since in most cases the code you'll have to run must be access-(de)controlled using method.setAccessible(true/false)