Need to convert variable contains String to a method call.
Example:
Variable:
//Enter the name and value of the locator
public String[] LoginID_Button = {"name","Log in"};
In my another class:
driver.findElement(By.name(loc1.LoginID_Button[1])).isDisplayed();
But I need to write as:
driver.findElement(By.loc1.LoginID_Button[0](loc1.LoginID_Button[1])).isDisplayed();
The name is the variable string but should be changed as Method. How to do this?
This is called Reflection. Which, is the ability to change structure/behavior in runtime.
This is a nice question about it.
For your problem, you can do the same as in that question's accepted answer.
driver.findElement(By.class.getMethod(loc1.LoginID_Button[0],String.class).invoke(null,loc1.LoginID_Button[1])).isDisplayed();
In the above code, the method getMethod() is used to dynamically find a method by its name which in this case LoginId_Butt[0]. It is required also to specify the type of the parameters that target method is accepting, in our case, it is String.
The found method is then invoked using the invoke() method. The invoke() method takes two arguments, the first one is the instance that the dynamic method is executed against. In our case, the instance is null because the dynamic method is static.
The second argument is a params of the arguments passed to the dynamic method. In this case, we have only one parameter to pass, that is LoginId_Butt[1].
Notes
Please don't forget to wrap this code with ty/catch against many exceptions can be thrown.
Please use the java naming convention for variable names i.e. loginID_Button
Related
This question already has answers here:
Reflection: get invocation object in static method
(4 answers)
Closed 7 years ago.
We all know that in Java you can call a static method as an instance method like this:
Foo foo = new Foo();
FooBar fooBar = foo.bar(); // bar is a static method on class Foo
What I want to know is:
Is there any way to determine inside bar whether bar was called statically (Foo.bar()) or called via a class instance as above?
If so, is there any way for bar to get a reference to the object which called it (in this case foo)?
Reason:
I am developing a kind of semantic syntax. I want my consumers to be able to put things like:
With.attribute("blah").and().attribute("blahblah"); // both "attribute" and "and" methods return an object of type "With"
Here you can see that attribute is being called both as a static and an instance method. However, you can't define a static and an instance method with the same name in Java, for the same reason as above - the static method could be called as an instance method and so to create an instance method with the same name would create ambiguity. Therefore I want to create a single method attribute which can be called both statically and non-statically, and inside the method body I want to try to determine if it was invoked statically or non-statically. The above questions will help me to assess the feasibility of doing this.
No, there is no way for the method to know whether it was called on a class or on an instance (at the JVM level there is no difference), and there is no way to get the instance that the method was called on.
The term for this kind of "semantic syntax" is domain-specific language (DSL).
Possible solution: name the static method withAttribute, then you could make it look like this:
withAttribute("blah").and().attribute("blahblah");
Java isn't made to do this, because it is not a very good thing to do.
If you want to be able to do something like this, why not do something like
new foo().withAttribute("blah").withAttribute("blahblah");
It really isn't a very good idea to do this at all.
Plus, why are you making your consumers use java code to give instructions? why not do something like
make a foo //Check for and chop off "make a" to get the object to create
add attribute blah //Check for and chop off "add attribute" to get the attribute to add
add attribute blahblah //Or, if you can add other things too, check for and chop off "add", then check for and chop off "attribute"
It seems like that would be much simpler.
Is it possible to count method calls efficiently? And without adding new class members (static counter variable)?
You could report calls via a static method hook that you provide. Then simply add an invokestatic instruction along with whichever arguments you want to pass. A naive approach would pass the method name and descriptor, but since this is all happening at runtime, you could avoid the string comparisons on each invocation by registering each method with your instrumentation API when you first scan the class, get back a simple token (an int or long), and modify each method to pass that token when calling the method which records the calls.
This question already has answers here:
How to get arguments passed to method that called this method?
(6 answers)
Closed 3 years ago.
How to get parameter values of the calling method?
I have scenario where there are two classes viz., Class A and Class B containing two methods mthA(in Class A) and mthB(in Class B). mthA calls mthB. now I want to know in mthB that what all parameters have been passed to mthA. This is basically for logging and handling exceptions. I am able to get the class name of the calling class i.e Class A and the method name which is calling mthB i.e mthA. but I am stuck at getting the parameters of mthA.
Thread.currentThread().getStackTrace()[1].getClassName()
this gives me the class name of the calling method i.e Class A.
Thread.currentThread().getStackTrace()[2].getMethodName()
This gives me the method name of the calling method i.e mthA.
If somehow I can get the whole method itself then I can get the method parameters passed to this method by using getParameters().
There's no easy way to get calling method's arguments values, (if you can not change the parameters of called method to include and pass calling parameters values).
Using some APIs like what Thread provides, we can get the static info like class/method name, but not runtime info like arguments values. One way could be to store and manage that kind of info somewhere and show when required in case of logging/exception. I dont think there's an API for that in java.
There is simplest way or is it necessary to use Reflection..?
If you want to know what parameter is passed for mthA then pass same parameter to mthB also Ex:
mthA(1stParam, 2ndParam, ...){
mthB(1stParam, 2ndParam, ..., OtherParamertsForMthB);
...
}
If it is just for logging purpose only, then you should log in mthA itself all the arguments passed into the method.
Why should mthB know about mthA's argument values to handle exceptions? If you are doing that, then you should consider refactoring the code and handle exceptions at the appropriate levels. If values passed to mthA is leading to an exception, then it should be handled there itself before calling mthB.
Reflection only helps in getting static information of the class and methods and does not provide runtime values of the arguments passed into a method.
Why don't you use some AOP tool like AspectJ to capture these values and log? You can use execution() point cut along with after() advice. For non production deployment you can log all the method calls along with passed values and returned value. This will be too much overhead for production env. For that you can just store the passed values (Object args[] as you get in AspectJ advice) in local variable and only log it in case of exception. But even in that case there will be some performance penalty as primitive values will be boxed to be passed as Object[] to your advice.
I have a Java method that takes 3 parameters, and I'd like it to also have a 4th "optional" parameter. I know that Java doesn't support optional parameters directly, so I coded in a 4th parameter and when I don't want to pass it I pass null. (And then the method checks for null before using it.) I know this is kind of clunky... but the other way is to overload the method which will result in quite a bit of duplication.
Which is the better way to implement optional method parameters in Java: using a nullable parameter, or overloading? And why?
Write a separate 3-parameter method that forwards to the 4-parameter version. Don't kludge it.
With so many parameters, you might want to consider a builder or similar.
Use something like this:
public class ParametersDemo {
public ParametersDemo(Object mandatoryParam1, Object mandatoryParam2, Object mandatoryParam3) {
this(mandatoryParam1,mandatoryParam2,mandatoryParam3,null);
}
public ParametersDemo(Object mandatoryParam1, Object mandatoryParam2, Object mandatoryParam3, Object optionalParameter) {
//create your object here, using four parameters
}
}
In Java, for each object, a new copy of instance variables is created which can be accessed using the object reference.
But in case of an instance method, only one copy of it(instance method) exists.
How is this method accessed by various object references?
The byte code (or native code if it's JIT'd) for the method is stored in one location. When the method is called, a pointer (under the hood, aka reference at a higher level) to the instance object is passed as the first argument so the method code can operate on that specific instance - have access to its fields, etc. In order to save space without additional performance cost, the calling mechanism in Java is quite a bit more complicated than C++, especially for interface methods.
Methods and fields are completely different. Methods apply to all instances of the object, but fields are per instance.
One way to think of it:
pretend the method is "global" to all instances, but it is "passed" an instance of the object via the "this" reference.
Methods can change the state of a particular instance, but they themselves are stateless.
Behind the scenes a reference to the object is passed to the method as part of the call. It may be useful to look at Java's reflection classes, Method.invoke() in particular.
From a previous answer of mine:
I'm sure the actual implementation is quite different, but let me explain my notion of method dispatch, which models observed behavior accurately.
Pretend that each class has a hash table that maps method signatures (name and parameter types) to an actual chunk of code to implement the method. When the virtual machine attempts to invoke a method on an instance, it gets the object's class, and looks up the requested signature in the class's table. If a method body is found, it is invoked, providing the original object as a reference called this.
Otherwise, the parent class of the class is obtained, and the lookup is repeated there. This proceeds until the method is found, or there are no more parent classes—which results in a NoSuchMethodError.
If a super class and a sub class both have an entry in their tables for the same method signature, the sub class's version is encountered first, and the super class's version is never used—this is an "override".
the implied reference "this" is passed in to each method, which of course you can reference explicitly
I'm assuming you're meaning on a simplistic level, as in how you actually do the call.
I'm also assuming you're refering to a method that has the static modifier in its signature, ie:
public static int getNum()
{
// code in here
return num;
}
If this is what you mean, and this was part of a class called 'SomeClass', then it would be accessed via the method call SomeClass.getNum(). ie, you put the actual class name before the method.
If this is not what you mean, ignore my answer :)