For example:
public class Demo{
public String getReflectString() {
return "string from reflect";
}
public String reflectMethod() throws Exception {
Method method = ReflectCase.class.getMethod("getReflectString");
return (String) method.invoke(this);
}
}
Method Demo#getReflectString called by reflection,and I wanna find a way to get all the methods in the program that are called this way.
I came up with a solution that has not yet been implemented.
Read the contents of the class file, start from the instruction, find the Method#invoke
instruction, and then look back to find the instance that calls the method, and then get the instance corresponding Class and MethodName.
However, this method has a problem, if Class or MethodName or even Method are passed as a parameter, it is difficult to find the corresponding content.
On this basis, think of ways to improve, traverse all the methods, check the instructions of the method. If got Method#invoke instruction in method A(), and Class and MethodName are passed in as parameters, record method A() and the order of parameters. In the following check, if there is a method call A(), you can get the value passed to method A() Parameters, to obtain the required value.
However, this solution requires traversing the entire program's instructions, which can be very time-consuming when the program is very large. If method call too many levels, the implementation of the algorithm can be quite complicated. So would like to ask, the feasibility of this idea, or is there any better way to solve the problem.
Thanks in advance.
Related
I saw the next class:
public static class DetailsFragment extends Fragment {
public static DetailsFragment newInstance(int index) {
DetailsFragment f = new DetailsFragment();
// Supply index input as an argument.
Bundle args = new Bundle();
args.putInt("index", index);
f.setArguments(args);
return f;
}
}
What i don't understand is why you can return a DetailsFragment type even though you´re just defining what a DetailsFragment is. For me (a novice), it's like searching a word in a dictionary and the definition uses the word itself to define it.
Please explain.
Thanks in advance.
Constructor versus static factory method
The static modifier on the newInstance method is the key. That modifier defines the method as standing apart, simply code to be run on its own, instead of defining behavior belonging to an object (an instance).
A static method is one of the parts of Java that is not object-oriented. Long story short, sometimes it is handy to just run a chunk of code without tying it to an object.
If you follow common Java naming conventions where a class is named with an initial upperclass character and an instance of that class is named with an initial lowercase letter, then you can easily spot the invocation of a static method.
DetailsFragment.newInstance() // A static method call made on a class. Not object-oriented.
detailsFragment.someMethod() // Instance method, invoked on one instance (one object) of type DetailsFragment named 'detailsFragment'.
So your newInstance method is not a constructor method. It is like a constructor method in that it aims to create an object. This kind of method is sometimes known as a factory method.
Your line of thinking is correct. A constructor that called new for the same class would cause an endless loop of object creating an object that creates an object and so on until the execution of your app failed. This repeating call to itself is known as recursion. If uncontrolled, recursion is bad, causing your app to fail. Recursion on a factory method would also be bad in the same way, running endlessly until failure.
But here we have a factory method calling the constructor via call to new. So, no uncontrolled recursion, no recursion at all.
If you are new to these concepts, it can be tricky to wrap your mind around them. For me, the key is that when my eyes reach any use of the static modifier I think "not object-oriented" and shift my brain out of OOP mode and switch into thinking in terms of plain procedural code.
Visually, I think of a class as a cookie cutter, objects/instances are the cookies being produced, and a static method is a note tied by a string to the cookie cutter. That static method really has nothing to do with the class, but tying it to a class gives us a place to be kept, a way for us to find and invoke that method later.
I am required to take all user input from within a void method (though it's important to note that the original verbiage says the method must not have a return value), and have all output be relegated to a separate method.
Now, I have all that set up and it's passing the relevant array to the sub method just fine (because I call the sub method from within the void method). But, I need the main to actually do the rest of the calling using the value from that sub method in other methods.
An in depth explanation and teaching would be deeply appreciated.
If you have luxury to change the signature of the methods (keeping the return type as void), you can pass another data structure to the methods. That way, you can get the user inputs inside GetUserInput(customDataStruct) method, pass it to SubMethod(customDataStruct) method. SubMethod() will modify the customDataStruct content, which will be available directly in main(), if main() invokes GetuserInput().
Second option, as #Fiddle suggested, is to use a global variable and let the methods manipulate it. This global variable shall be accessible from main().
I had it flipped. By letting the void method be the sub method and actually learning to pass by reference (enjoy my head smacking) I was able to use the method with the return to bring the value back to main.
How can I inspect the bytecode of a class (using something such as ASM) to learn which initial values were passed through to a method?
For example: Given some methods that pass values to each other:
void m1(Object o) {
Object v = o;
m2(v);
m2("box");
}
void m2(Object o) {
Object v = o;
m3(x);
}
void m3(Object o) {
}
And some method calls, all defined in the same class:
{
Object foo = "foo";
m1(foo);
m2("bar");
m3("baz");
}
How can I inspect the class' bytecode to learn that m3 will be called 4 times with the values "foo", "box", "bar" and "baz"?
Using ASM, you can in theory trace for each method if another method of the same class is invoked from within it. The visitor API's method that is responsible for defining method invocations is visitMethodIns. Assuming that your class was called bar.Foo, you would need to trace:
visitMethodIns(<any>, "bar.Foo", <any>, <any>)
You would then need to build a transitive relation of methods calling each other where the last two parameters allow you to build such a relation hierarchy. Additionally, you would need to trace the arguments of these method invocations, what is more tricky but not impossible either.
The reason it is more complex is the number of possible ways an argument can be loaded onto the operand stack. For your example, you only need to pay attention to the visitIns and the visitLCDIns callbacks.
When calling a method on a constant pool value (LCD), the resolution of the argument is rather trivial. You would however need to trace the entire instruction chain before calling a method to learn of the local variable assignment in order to know that you are calling the method on the method parameter. Thus, you could find out that
ALOAD_0 / ASTORE_1 / ALOAD_1 => ALOAD_0
is an effective result of a sequence of reads/writes form the methods local variable array.
With all this, from parsing the byte code, you would learn about the following call-transitions:
m1(Ljava/lang/Object)V -> m2(Ljava/lang/Object)V [ALOAD 0]
-> m2(Ljava/lang/Object)V [LCD "box"]
m2(Ljava/lang/Object)V -> m3(Ljava/lang/Object)V [ALOAD 0]
You could then use these results to parse your block where you find out about these method calls and their implications. You would however have created a quite fragile solution where indirections such as:
{
Foo foo = this;
foo.m1("bar");
}
would not be discovered. As pointed out in the comments, you basically need to emulate the Java virtual machine in order to "run" your code.
And even if you implement a complex solution to trace all this, you could still not be sure of your result. What happens when I invoke an interface method from within an implementation. Or a method of a subclass? Thanks to the dynamic dispatch of methods, you can never be sure of the target that is called.
A professor of mine once said that the following code should never be done:
System.out.println(object.toString());
He said (and I believe cited "Effective Java") it causes a double call. Since the print statement calls the toString method of an object, it would be less efficient to have the toString method called twice. The preferred method would be to just use:
System.out.println(object);
Obviously this way looks better in code and would save time. I will always do it like this no matter what, but my question is "Is this actually more EFFICIENT?". In looking through the PrintStream documentation, the print method has been overloaded to take a String as the parameter (which would be the case if the toString method were called first). I am not seeing where that version of the print method calls the toString method of the inputted parameter and I don't believe it would make sense for it to do that.
Also, sorry if this is a duplicate. I couldn't find any topics on it.
Your examples call two different methods in PrintStream. Both call toString() at most once.
The first method calls println(String x), which does not call
x.toString() itself.
The second method calls println( Object x ), which leads to a call of
x.toString() if x is not null.
However, there is a potential advantage to using System.out.println(object). If object is null, this prints "null". The other statement throws a NullPointerException.
No, it is not more efficient -- precisely because of the overload that you mentioned. Moreover, a call of toString on a String is extremely quick, so even without an overload the difference would not be measurable.
However, your professor is right about not making the call like System.out.println(object.toString());, but the reason is different: since the call is unnecessary, the readers of your code may get confused.
in a multithreading environment calling System.out.println is actually bad enough, even much worst than a unneeded call to toString. The "problem" exist because you have a synchorized call inside "println":
public void println() {
newLine();
}
private void newLine() {
try {
synchronized (this) {
ensureOpen();
...
}
So, if you are trying to write efficient java, you could start by avoiding it. As an alternative you could use any of the different logging mechanism, e.g. http://www.slf4j.org/
Following this tutorial:
http://developer.android.com/training/notepad/notepad-ex2.html
In Step 2, this method gets called:
registerForContextMenu(getListView());
which is a public method of Activity. Now, I'm a bit of a Java newbie here - I thought if you wanted to call an instance method of a superclass you needed to preface it with this. E.g.
this.registerForContextMenu(getListView());
Is it just a style thing here? Is there any difference between
this.registerForContextMenu
and simply
registerForContextMenu
No, there is no difference.
You don't have to use this., but it is often done anyway to make the code clearer.
For one thing, it makes it easy to tell if a method is static or not if you use the convention of calling instance methods like this:
this.registerForContextMenu()
and static methods like this:
ClassName.staticRegisterForContextMenu()
you do not have to use this. If you ommit it it is assumed you called method in this scope. One particular example when this may help could be i.e.:
Boolean someVar;
public function setMe( Boolean someVar ) {
this.someVar = someVar;
}
In this case, w/o this you would get the error.
To call a method of superclass either you need object of superclss or keyword super .
eg.
superObject.superclassMethod();
super.superclassMethod();
this is a reference of the current object. this can be used to call method of a class in which it is used. this can never be used to call a superclass method.
As for
this.registerForContextMenu()
and
registerForContextMenu()
no such difference. you can use either of them.
Both ways are correct for calling a method on the current (this) instance of the class. Non private methods are inherited from super classes, so you can use the same syntax to call such methods.