My goal is to create a MethodHandle that, by passing a class and a field name, reads that field with a MethodHandle getter and returns the value.
With this method I wanted to return an arbitrary object:
return new ConstantCallSite(MethodHandles.lookup().unreflectGetter(f).asType(MethodType.methodType(Object.class))).dynamicInvoker();
I received the Field f via Reflections.
The problem now is that when this method is executed, the typical error for invokeExact (WrongMethodTypeException) occurs:
WrongMethodTypeException: cannot convert MethodHandle(TestClass)String to ()Object
This also applies to ints, floats, etc.
In another thread I also already read that you can use invokeExact dynamically if the return of MethodHandle is changed to Object.
Here is a code snippet from the method, which makes use of passing a static final MethodHandle:
return (T) handle.invokeExact(testObject);
Using MethodHandle#invoke is rather out of the question for me, as I'm after performance. Without invokeExact I could possibly also fall back on using only reflections.
Does anyone know a way to do this or a workaround with similar performance? The latter plays a big role in the project. I thank those in advance who could possibly help with this problem.
A (non-static) getter needs an instance to retrieve the field's value from. You should be able to make this work by adding another Object parameter to the erased method type:
return MethodHandles.lookup().unreflectGetter(f).asType(MethodType.methodType(Object.class, Object.class));
(Also, there's no need to wrap the thing in a ConstantCallsite)
Related
Currently, I am creating some end to end tests for an API and have a method that would be perfect to use for a test except for the fact that it has a return type of void. If I were to change the return type to List, could this possibly break existing functionality somewhere within the system? My current thoughts are that all code that calls the method will not be affected as they are not using the method to assign any value to a variable. Are there any cases in which this is not true?
This is for a legacy code base, so unfortunately I am stuck with it. The codebase is too vast for me to look up all instances of code that could be affected by this change.
You're right. You can easily change the return type from void to another object since it could never be used before.
I have come across this code (simplified of course) in the project I have been assigned to.
Method Option 1
public myType getSomething(final int pTeamId) {
this.teamId = pTeamId;
final ClassABC classABC = new ClassABC(pTeamId);
...
return myType;
}
Notice how the input parameter pTeamId is being assigned to the private data member teamId in the first line of the method. Please note that there are getter and setter methods for this teamId data member (Which I have not bothered to include for simplicity's sake. Just know they are a standard getter/setter pair).
So I suppose I could write this method differently where I call the getter of the data member I just set instead of using the input parameter passed in directly as in Method Option 1:
Method Option 2
public myType getSomething(final int pTeamId) {
this.teamId = pTeamId;
final ClassABC classABC = new ClassABC(this.getTeamId());
...
return myType;
}
I realize this question may seem trivial and/or stupid to some, but I am encountering this situation frequently in a large code base I am modifying, so I am curious about which is the "correct" way to approach this, Method option 1 or Method option 2.
I came across this thread, but it targets JavaScript: speed of getter function vs direct access
My first inclination is to use Method Option 1, but I really do not have a good reason why, besides that "it looks faster...".
Can someone else provide a better reason(s)?
Specifically,
1) Is there is a proper/preferred convention/technique/practice in this scenario?
and
2) WHY is one option better than the other? Are they equal? Are there performance issues? etc.
Are there questions I am not asking? (or is this all an over-analysis)?
Any insight would be appreciated.
The getter could have logic in it like not returning null but an empty string instead.
same with the setter.
when you manipulate the variable directly you don't execute that logic.
this can also be a problem if someone overrides the getter and setter logic. (you can forbidd this by making them final) but this is not a common doing! (i would go one step further and call it an anti-pattern)
i would suggest always calling the getters/setters. and there is no real performance loss
I have Selenium test which fills a form. I have a method for it but this method has overgrown in terms of number of parameters -
newMerchantPage.addEditMerchant(merchantDomain, merchantName,
merchantCategory, true, merchantDescription, merchantNotes,
merchantTags, true, true, false, false, merchantTitle,
additionalDescription, merchantHeading, dummyCouponLink, true);
There are only Strings and boolean.
I was thinking to use collection and then iterate through collection in called method to do some more processing. Though yet not sure if this is the way to go about. Any recommendations?
MODIFIED METHOD:
After implementing couple of sugggestions my method (of a different method) call looks like -
ContactPage contactPage = new ContactPage(driver);
setContactFormData();
contactPage.setName(name).setEmailAddress(emailAddress).setSubject(subject).setM essage(message);
contactPage.submitContactForm(contactPage);
submitContactForm in turn calls different utility methods. How bad does it look? Especially the last line (method call on object and same object being passed as argument) ?
One common approach is to wrap the parameters in a class. This class could then provide set-methods which return this to allow for a nice chaining. (See ProcessBuilder for a good example.)
Example:
MerchantData data = new MerchantData(); // initialize with sensible defaults
data.setDomain("example.com")
.setName("Some Name")
.setTags("tag1, tag2);
newMerchantPage.addEditMerchant(data);
I'm assuming that you are using Selenium server (or RC).
The suggestions for wrapping the data up into a Merchant class are all good and make sense, especially from pure Java coding point of view.
However, your main point of concern here in Selenium is the form you are filling, rather that the merchant domain object.
Maybe you could then break your method up into smaller methods such as
openMerchantForm(...)
typeNameInMerchantForm(...)
chooseMerchantCategory(...)
and so on, depending on what type of control is being set on the form. That will reflect the behaviour you are testing rather than setting the domain objects directly etc.
Hope that helps.
Maybe - write a class Merchant, create an instance with the method value and pass the instance instead?
newMerchantPage(Merchant merchant);
The advantage: you can keep the test parameters in files and do something like:
Merchant merchant = new Merchant();
merchant.populate(File testdata, int record);
Have you considered making a class that is if the parameters you specify belong to something same,then pass the object as the parameter.
After passing an object into a method, I would like to change one of its fields. What's the best practice to do this task in Java?
Simple answer
As stated in other answers, you can simply call the setter method.
More philosophical answer
Generally, it can be dangerous to mutate objects in a scope other than that in which they were created:
http://en.wikipedia.org/wiki/Functional_programming
That said, there are often times where you simply want to encapsulate bits of logic in the same logical scope where you would want to modify values of an object passed in. So the rule I would use is that as long as all calling code is fully aware of such mutations, you can call the setter method on the object (and you should create a setter method if you don't have one) in the method to which you're passing the object.
In general, if you call a function that mutates parameters from multiple places in your codebase, you will find that it becomes increasingly error prone, which is why functional programming pays off.
So, the moral of the story is: if your caller(s) are fully aware of such mutations, you could change the value in your method, but in general you should try to avoid it and instead change it in the scope in which it was created (or create a copy).
Be aware of the fact that even if the object is passed as final it still can be changed. You just can't reassign the variable, which normally is desired for an (input/)output parameter.
Taking Jigar Joshis example:
public void increasePersonAgeByOneMonth(final Person p ){
p = new Person(); //this won't work, which is ok since otherwise the parameter itself would not be changed by the next method
p.setAge(((p.getAge()*12.0) + 1)/12.0); //ok
}
I have an object that has a lot of attributes, each one with it's getter and setter. Each attribute has a non primitive type, that I don't know at runtime.
For example, what I have is this:
public class a{
private typeA attr1;
private typeB attr2;
public typeA getAttr1(){ return attr1; }
public typeB getAttr2(){ return attr2; }
public void setAttr1(typeA at){ attr1 = at; }
public void setAttr2(typeB at){ attr2 = at; }
}
public class typeA{
public typeA(){
// doesn't matter
}
}
public class typeB{
public typeB(){
// doesn't matter
}
}
So, using reflection, I obtained the setter method for an attribute. Setting a value in the standard way is something like this:
a test = new a();
a.setAttr1(new typeA());
But how can I do this using reflection? I already got the setAttr1() method using reflection, but I don't know how to create a new typeA object to be inserted in the setter.
Use Class#newInstance().
Class<TypeA> cls = TypeA.class;
TypeA typeA = cls.newInstance();
Or, in your specific case when you have to determine the type of the method parameter:
Class<?> cls = setterMethod.getParameterTypes()[0];
Object value = cls.newInstance();
setterMethod.invoke(bean, value);
You can learn more about reflection in Sun tutorial on the subject. That said, classnames ought to start with uppercase. I've corrected it in the above example.
By the way, instead of reinventing the Javabean reflection wheel, you may find one of the tools mentioned here useful as well.
Use getDeclaredFields() method in the Class object, to get all fields, then use field.set(classInstance, value) to set the value of field in an instance. Note: you may have to set the accessible flag on the field to true, if the field is private. No need to rely on setter methods.
I encountered this on some stuff I was doing. My general conclusion was that whenever I felt like I needed a class with a bunch of fields I was doing it wrong. Here's my thought process:
Problem:
- I need a large number of fields to hold this data
- All these fields require huge amounts of boilerplate
Solution:
use reflection to reduce the boilerplate < "you are here"
Use metadata to specify how the fields should be used
New Problems:
Reflection is difficult to understand when someone new looks at the code
Once you go meta enough to eliminate more boilerplate, the fields often have no mention in the code except through the metadata--why are they fields?
Specifying the metadata in code becomes bulky quite quickly (easiest way is a string array, by the way)
Solution: Start storing data in a collection and Specify metadata in an external data file
New problem: Errors become hard to find
Be meticulous about error checking and very explicit with your error messages. Make sure any other programmers that might use your code read the error messages. Attempt to indicate when metadata is missing or wrong and how the programmer should update the metdata--include the location of the metadata file.
Problem: No type safety
Yeah, this became somewhat annoying at times. I ended up including type information in the metadata so that if someone put the wrong value in a field, it could be detected--essentially this moves type safety from build time to run time which was fine in my case.
Problem: The metadata is needed repeatedly throughout the life of the object
Rather than looking it up by name every time it's used, I'd parse the metadata at the beginning and put it in an object (call it an IntHolder). This holder would end up in the hashtable and it would contain the current value as well as a reference to the parsed metadata.
Example
Here's what my metadata would end up for one field of a style sheet:
FieldName: Age
FieldType Integer
ScreenBinding: AgeTextField
DBBinding: User.age
Validation: IntRange(0, 120); "Age is out of range"
The field name might be how it is displayed to the user or just for use in your program. In general, you shouldn't need to directly manipulate this type of data by name--but of course you do sometimes.
When you do need to use, use getInt("Age") and setInt("Age", 12) instead of getAge() and setAge(12)--slightly more verbose but not really a problem.
If it is a problem, you can make getAge/setAge helper methods and you never need to know it's not a field, but that does start piling on the boilerplate again.
FieldType: specifies how it's stored and lets you implement type checking.
ScreenBinding and DBBinding are used to copy the value into and out of other systems. I also used this type of mechanism to transfer the data from server to client and back.
The fun one is Validation. When pulling data off the screen it can be passed to a validator in a very progmatic way. The same validator can be used before committing to the DB.
Validators can do a lot more than that, they can act as triggers (if a value changes, do this) or actions (when user submits a screen, do this). These are a simple objects with the ability to take a value (through an interface)--they can be as flexible or powerful as you like but are not tied directly to any object except through the meta-data.
The only problem with this approach is you have to be the type of programmer that enjoys writing fixtures instead of error-prone boilerplate. (Yes, I find that the amount of time is about equal, but I tend to get really slow when I have to implement boilerplate)
After doing this a few times I really love the pattern, but it gets difficult to implement. Next time I do it I'm going to try to make it into a library of some type.
If you want to set a "fresh" object in each setter of your class, you can typically do it by getting the Method, for each Method you get the Class of the arguments with getParameterTypes() , for each Class you invoke Class.newInstance() ... and cross your fingers (that should break with primitive types -I doubt Java does autoboxing here).
You can always ask if a parameter is a pimitive calling isPrimitive()
Why would you want to set "empty" instances for primitive fields of a class? They are already initialized. Do you want to "reset" them ?