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 ?
Related
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)
Lets have these two getters in Kotlin:
data class Foo(var id: String){
val reference get() = Reference("Patient/$id")
}
data class Foo(var id: String){
fun getReference(){ return Reference("Patient/$id") }
}
Does the first one have some performance cons? I like it more, but I am not sure if they are built into same bytecode, or the first one adds more things, because I am basically delaring new variable and not just method.
In your example, they are equivalent behind the scenes (but obviously, you need different syntax for using the property vs. the method). Specifically, Kotlin will generate a backing field if any of the accessors use the field identifier, and the autogenerated get and set accessors do use field. So in order to avoid a backing field, you need to supply your own get accessor and (in the case of a var property) a set accessor, and none of them must use field.
Whether a property has a backing field or not, reading the property turns into a method call to get() behind the scenes, and if it's a var, assigning to the property turns into a method call to set().
Note that it's possible to get into weird situations with var if your accessors are inconsistent: var foo: Int = 3; get() = 42 will always return 42 when you read it, irrespective of the initial value and whatever you might assign to it, because you will get an autogenerated backing field since you omitted the setter, and that's what the autogenerated setter will set.
Using properties instead of Java-style getter/setter methods is strongly preferred in Kotlin.
(Thanks to #AlexeyRomanov for pointing out the specific rules.)
I have a method that will process a Collection<Nodes> that is passed in as a parameter. This Collection will be modified, therefore I thought it would be good to first make a copy of it. How do I name the parameter and local variable, e.g. nodes in the example below?
List<Nodes> process(Collection<Nodes> nodes) {
List<Nodes> nodes2 = new ArrayList<>(nodes);
...
}
As another example consider the following where the variable is an int parsed from a String parameter:
public void processUser(final String userId) {
final int userId2 = Integer.parseInt(userId);
...
A good approach to the name variables problem is to use names that suggest the actual meaning of the variable. In your example, you are using names that do not say anything about the method functionality or variables meaning, that's why it is hard to pick a name.
There are many cases like yours in the JDK, e.g. Arrays#copyOf:
public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) {
#SuppressWarnings("unchecked")
T[] copy = ((Object)newType == (Object)Object[].class)
? (T[]) new Object[newLength]
: (T[]) Array.newInstance(newType.getComponentType(), newLength);
System.arraycopy(original, 0, copy, 0,
Math.min(original.length, newLength));
return copy;
}
In this case they call the parameter original and the local variable copy which perfectly expresses that the returned value is a copy of the parameter. Precisely, copying is what this method does and it is named accordingly.
Using the same reasoning for your case (consider refactoring to give more meaningful names to your method and variables) I would name your local copy of nodes something like processedNodes, to express what that variable is and to be consistent with your method's name.
Edit:
The name of the new method you added in your edit does not provide hints about what it does either. I'll assume that it modifies some properties (maybe in a database) of the user whose id is passed via parameter.
If that is the case (or similar), I think that an appropriate approach you
could apply would be that every method should have a single responsibility. According to your method's name it should process the user, for that you need an int userId. The responsibility of parsing an String userId should be out of the scope of this method.
Using the proposed approach has, among others, the following advantages:
Your class won't change if you have to add additional validation to your input.
Your class won't be responsible for handling NumberFormatException which must be the application responsibility.
Your processUser method won't change if you have to handle different types of inputs (e.g. float userId).
It ultimately comes down to what you want to communicate to future programmers. The computer obviously doesn't care; it's other people you're talking to. So the biggest factor is going to be what those people need to know:
What is the logical (abstract, conceptual) meaning of this variable?
What aspects of how this variable is used could be confusing to programmers?
What are the most important things about this variable?
Looking at your first example, it's kind of hard to understand enough about your program to really choose a good name. The method is called process; but methods generally speaking implement computational processes, so this name really doesn't tell me anything at all. What are you processing? What is the process? Who are you processing it for, and why? Knowing what the method does, and the class it's in, will help to inform your variable name.
Let's add some assumptions. Let's say you're building an application that locates Wi-fi access points in a building. The Node in question is a wireless node, with subclasses Repeater, AccessPoint, and Client. Let's also say it's an online-processed dataset, so the collection of nodes given may change at any time in response to a background thread receiving updates in what nodes are currently visible. Your reason for copying the collection at the head of the method is to isolate yourself from those changes for the duration of local processing. Finally, let's assume that your method is sorting the nodes by ping time (explaining why the method takes a generic Collection but returns the more specific List type).
Now that we better understand your system, let's use that understanding to choose some names that communicate the logical intention of your system to future developers:
class NetworkScanner {
List<Node> sortByPingTime(Collection<Node> networkNodes) {
final ArrayList<Node> unsortedSnapshot;
synchronized(networkNodes) {
unsortedSnapshot = new ArrayList<>(networkNodes);
}
return Utils.sort(unsortedSnapshot, (x,y) -> x.ping < y.ping);
}
}
So the method is sortByPingTime to define what it does; the argument is networkNodes to describe what kind of node we're looking at. And the variable is called unsortedSnapshot to express two things about it that aren't visible just by reading the code:
It's a snapshot of something (implying that the original is somehow volatile); and
It has no order that matters to us (suggesting that it might have, by the time we're done with it).
We could put nodes in there, but that's immediately visible from the input argument. We could also call this snapshotToSort but that's visible in the fact that we hand it off to a sort routine immediately below.
This example remains kind of contrived. The method is really too short for the variable name to matter much. In real life I'd probably just call it out, because picking a good name would take longer than anyone will ever waste figuring out how this method works.
Other related notes:
Naming is inherently a bit subjective. My name will never work for everyone, especially when multiple human languages are taken into account.
I find that the best name is often no name at all. If I can get away with making something anonymous, I will--this minimizes the risk of the variable being reused, and reduces symbols in IDE 'find' boxes. Generally this also pushes me to write tighter, more functional code, which I view as a good thing.
Some people like to include the variable's type in its name; I've always found that a bit odd because the type is generally immediately obvious, and the compiler will usually catch me if I get it wrong anyway.
"Keep it Simple" is in full force here, as everywhere. Most of the time your variable name will not help someone avoid future work. My rule of thumb is, name it something dumb, and if I ever end up scratching my head about what something means, choose that occasion to name it something good.
I used to give names, which reflect and emphasize the major things. So a potential reader (including myself after a couple of months) can get immediately, what is done inside the method just by its signature.
The API in discussion receives an input , does some processing and returns the output. These are the three main things here.
If it is not important, what processing is done and what is the type of input, the most generic is this form:
List<Nodes> process(Collection<Nodes> input) {
List<Nodes> output = new ArrayList<>(input);
...
}
and
public void process(final String input) {
final int output = Integer.parseInt(input);
...
If it is important to provide more information about processing and type of an input, names like: processCollection, inputCollection and processUser, inputUserId are more appropriate, but the local variable is still the output - it is clear and self-explained name:
List<Nodes> processCollection(Collection<Nodes> inputCollection) {
List<Nodes> output = new ArrayList<>(inputCollection);
...
}
and
public void processUser(final String inputUserId) {
final int output = Integer.parseInt(inputUserId);
...
It depends on the use case and sometimes it is even more appropriate to elaborate the processing, which is done: asArray or asFilteredArray etc instead of processCollection.
Someone may prefer the source-destination terminology to the input-output - I do not see the major difference between them. If this serves telling the method story with its title, it is good enough.
It depends on what you are going to do with the local variable.
For example in the first example it seems that is likely that variable nodes2 will actually be the value returned in the end. My advice is then to simply call it result or output.
In the second example... is less clear what you may want to achieve... I guess that userIdAsInt should be fine for the local. However if an int is always expected here and you still want to keep the parameter as a String (Perhaps you want to push that validation out of the method) I think it is more appropriate to make the local variable userId and the parameter userIdAsString or userIdString which hints that String, although accepted here, is not the canonic representation of an userId which is an int.
For sure it depends on the actual context. I would not use approaches from other programming languages such as _ which is good for instance for naming bash scripts, IMO my is also not a good choice - it looks like a piece of code copied from tutorial (at least in Java).
The most simple solution is to name method parameter nodesParam or nodesBackup and then you can simply go with nodes as a copy or to be more specific you can call it nodesCopy.
Anyway, your method process has some tasks to do and maybe it is not the best place for making copies of the nodes list. You can make a copy in the place where you invoke the method, then you can simply use nodes as a name of your object:
List<Nodes> process(Collection<Nodes> nodes) {
// do amazing things here
// ...
}
// ...
process(new ArrayList<>(nodes))
// ...
Just my guess, you have got a collection and you want to keep the original version and modify the copy, maybe a real solution for you is to use java.util.stream.Stream.
Simply put, when naming the variable, I consider a few things.
How is the copy created? (Is it converted from one type to another?...)
What am I going to do with the variable?
Is the name short, but/and meaningful?
Considering the same examples you have provided in the question, I will name variables like this:
List<Nodes> process(Collection<Nodes> nodes) {
List<Nodes> nodesCopy = new ArrayList<>(nodes);
...
}
This is probably just a copy of the collection, hence the name nodesCopy. Meaningful and short. If you use nodesList, that can mean it is not just a Collection; but also a List (more specific).
public void processUser(final String userId) {
final int userIdInt = Integer.parseInt(userId);
...
The String userId is parsed and the result is an integer (int)! It is not just a copy. To emphasize this, I would name this as userIdInt.
It is better not to use an underscore _, because it often indicates instance variables. And the my prefix: not much of a meaning there, and it is nooby (local will do better).
When it comes to method parameter naming conventions, if the thing a method parameter represents will not be represented by any other variable, use a method parameter name that makes it very clear what that method parameter is in the context of the method body. For example, primaryTelephoneNumber may be an acceptable method parameter name in a JavaBean setter method.
If there are multiple representations of a thing in a method context (including method parameters and local variables), use names that make it clear to humans what that thing is and how it should be used. For example, providedPrimaryTelephoneNumber, requestedPrimaryTelephoneNumber, dirtyPrimaryTelephoneNumber might be used for the method parameter name and parsedPrimaryTelephoneNumber, cleanPrimaryTelephoneNumber, massagedPrimaryTelephoneNumber might be used for the local variable name in a method that persists a user-provided primary telephone number.
The main objective is to use names that make it clear to humans reading the source code today and tomorrow as to what things are. Avoid names like var1, var2, a, b, etc.; these names add extra effort and complexity in reading and understanding the source code.
Don't get too caught up in using long method parameter names or local variable names; the source code is for human readability and when the class is compiled method parameter names and local variable names are irrelevant to the machine.
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
Lets say there is a method that searches for book authors by book id. What should be passed as a parameter to such method - only book.id (int) or whole book object?
Or another example. In java I need to do some work with current url of the page. What should be passed to such method - only request.getRequestURL() or whole request?
I kind of see benefits from each method but can't come up with good rule when to use what.
Thanks.
I am not sure if there is a "rule" to what is best, but I most often pass just the paramaters I need into the method. So in your first example I would only pass in the book.id and in your second example I would only pass in the request.getRequestURL().
I try to avoid passing in more than I need.
I'm going to be a dissenter and argue for passing the entire Book object.
Reason 1: Type checking. If you just pass an integer ID, there's no way to know, looking at code, if you've got the correct "kind" of integer ID. Maybe you've been passing around an integer variable that you think is the Book ID, but it's actually the Author ID. The compiler is not going to help you catch this mistake, and the results are going to be buggy in unexpected ways.
Reason 2: Future proofing. Some have made the argument that if you just pass the ID, you give yourself the option to change the structure of the Book object later, without breaking the doSomethingWithBook(int ID) method. And that's true. On the other hand, if you pass the entire Book object, you give yourself the option to change the internals of doSomethingWithBook(Book book) (maybe it will want to search based on some other field in the future) without breaking any of the (possibly numerous) places you've called doSomethingWithBook. I'd argue that the latter helps you more.
In the case of the Request, I would give a different answer, since I would consider a Request object to be tightly linked to a certain type of interface (web) and therefore would want to limit the use of that object. One question I like to ask myself: if I wanted to switch this web application to be, say, a command-line application, how many classes would have to change? If I'm passing around the Request, that's going to "infect" more classes with web-specific logic.
Weaker connectivity is preferred unless there are specific reasons. When pass book id only to search method you are free to change Book interface without worrying that it might affect other functions. At some moment in future you may discover that you need to do exactly the same job with some URL outside request handler, so avoiding unneeded dependency on request is good. But note, that if you frequently call do_smth(request.getRequestURL()) it may become quite annoying.
This is related to the Law of Demeter, which basically states that objects and methods should only receive exactly what they need, rather than going through another object to get what they actually need. If you need to use multiple fields from a Book in your method, it might be better to just take a book. But in general, you'll have less coupling in a system if you only depend on exactly what you need.
In both your examples, just using the ID or URL would probably be preferable. Particularly in the case of the URL, where (if you want to test the method) it's easy to create a URL to test with but harder (and completely unnecessary) to create a request to pass to the method which will then only use the URL anyway. The method also becomes more generally applicable to other situations than one in which you have a request object.
I would give each method only as much as necessary (so for the second question: just give it request.getRequestURL()).
For the first one I would think about defining both methods (but prefer the id-one, as you can easily get the ID if you have a Book, but not the other way around).
findAuthorsForBookId(int bookId)
findAuthorsForBook(Book b)
Call book.authors().
(Note: this is a dissenting view regarding the accepted answer.)
Well, there is an implicit rule set in context of domain modeling. If the receiver is performing tasks independent of the domain model then you pass the field. Otherwise, you should pass the object and the model specific action is made explicit by the act of the receiver accessing the id property of the 'Book' object. Most importantly, if accessing the property ever evolves beyond simply returning the reference of a field (e.g. certain actions in the property accessor) then clearly you do NOT want to chase all instances in your code where you dereferenced the property before passing it into various methods.
Further considerations are the consequences (if any) of accessing the field before the call cite, or, inside the receiver.
There's no rule actually, you should be straightforward with the info you need, in that case the book.id. If you consider extending / sharing your search in the future, the you can have an overloaded method to accept a book object so that you can search by other attributes of the book object.
Think about maintaining the code in the long run. Any method you expose is a method you'll have to support for your users going forward. If bookId is all that's needed for the forseeable future, then I'd go with just passing in that: that way, anyone who has a bookId can use your method, and it becomes more powerful.
But if there's a good chance that you may need to refactor the lookup to use some other attributes of Book, then pass in Book.
If you're writing a DAO of sorts, you should consider having a BookSelector which can be built up like: new BookSelector().byId(id).bySomethingElse(somethingElse) and pass this selector instead of having a proliferation of findByXYZ methods.
I agree with the previous posters. I wanted to add that if you find yourself needing multiple properties of the object (id, title, author) then I'd suggest passing the object (or an interface to the object). Short parameter lists are generally preferable.
Lets say there is a method that searches for book authors by book id. What should be passed as a parameter to such method - only book.id (int) or whole book object?
I am making the assumption that "book authors" is an attribute of a book. Therefore, I imagine something like the following class:
class Book {
private int id;
private List<Author> authors;
// ... maybe some other book information
public int getID() {
return this.id
}
public void setID(int value) {
this.id = value
}
public List<Author> getAuthors() {
return this.authors.clone();
}
// ...
}
Given an instantiated Book object (aBook), to determine the list of authors, I would expect that I can call aBook.getAuthors(), which requires no parameters.
I would discourage the creation of partially instantiated domain objects. In other words, given a bookid, and looking for a list of authors, I would want the client code to look more like this:
Book aBook = library.findBook(bookid);
List<Author> authors = aBook.getAuthors();
and less like this:
Book bookQuery = new Book().setID(bookid); // partially instantiated Book
Book aBook = library.findBook(bookQuery);
List<Author> aBook = book.getAuthors();
The first version reduces the number of throwaway objects that are created by the client code. (In this case, bookQuery, which isn't a real book.)
It also makes the code easier to read--and therefore to maintain. This is because bookQuery is not doing what the maintenance programmer would expect. For example, I'd expect two Books with the same ID to have the same tite, authors, ISBN, etc. These assertions would fail for bookQuery and aBook.
Thirdly, it minimizes the chance that you will someday pass an invalid (partially instantiated) Book object to a method that is expecting a real Book. This is a bug where the failure (in the method) may happen far away from the cause (the partial instantiation).