Best practice for passing many arguments to method? - java

Occasionally , we have to write methods that receive many many arguments , for example :
public void doSomething(Object objA , Object objectB ,Date date1 ,Date date2 ,String str1 ,String str2 )
{
}
When I encounter this kind of problem , I often encapsulate arguments into a map.
Map<Object,Object> params = new HashMap<Object,Object>();
params.put("objA",ObjA) ;
......
public void doSomething(Map<Object,Object> params)
{
// extracting params
Object objA = (Object)params.get("objA");
......
}
This is not a good practice , encapsulate params into a map is totally a waste of efficiency.
The good thing is , the clean signature , easy to add other params with fewest modification .
what's the best practice for this kind of problem ?

In Effective Java, Chapter 7 (Methods), Item 40 (Design method signatures carefully), Bloch writes:
There are three techniques for shortening overly long parameter lists:
break the method into multiple methods, each which require only a subset of the parameters
create helper classes to hold group of parameters (typically static member classes)
adapt the Builder pattern from object construction to method invocation.
For more details, I encourage you to buy the book, it's really worth it.

Using a map with magical String keys is a bad idea. You lose any compile time checking, and it's really unclear what the required parameters are. You'd need to write very complete documentation to make up for it. Will you remember in a few weeks what those Strings are without looking at the code? What if you made a typo? Use the wrong type? You won't find out until you run the code.
Instead use a model. Make a class which will be a container for all those parameters. That way you keep the type safety of Java. You can also pass that object around to other methods, put it in collections, etc.
Of course if the set of parameters isn't used elsewhere or passed around, a dedicated model may be overkill. There's a balance to be struck, so use common sense.

If you have many optional parameters you can create fluent API: replace single method with the chain of methods
exportWithParams().datesBetween(date1,date2)
.format("xml")
.columns("id","name","phone")
.table("angry_robots")
.invoke();
Using static import you can create inner fluent APIs:
... .datesBetween(from(date1).to(date2)) ...

It's called "Introduce Parameter Object". If you find yourself passing same parameter list on several places, just create a class which holds them all.
XXXParameter param = new XXXParameter(objA, objB, date1, date2, str1, str2);
// ...
doSomething(param);
Even if you don't find yourself passing same parameter list so often, that easy refactoring will still improve your code readability, which is always good. If you look at your code 3 months later, it will be easier to comprehend when you need to fix a bug or add a feature.
It's a general philosophy of course, and since you haven't provided any details, I cannot give you more detailed advice either. :-)

First, I'd try to refactor the method. If it's using that many parameters it may be too long any way. Breaking it down would both improve the code and potentially reduce the number of parameters to each method. You might also be able to refactor the entire operation to its own class. Second, I'd look for other instances where I'm using the same (or superset) of the same parameter list. If you have multiple instances, then it likely signals that these properties belong together. In that case, create a class to hold the parameters and use it. Lastly, I'd evaluate whether the number of parameters makes it worth creating a map object to improve code readability. I think this is a personal call -- there is pain each way with this solution and where the trade-off point is may differ. For six parameters I probably wouldn't do it. For 10 I probably would (if none of the other methods worked first).

This is often a problem when constructing objects.
In that case use builder object pattern, it works well if you have big list of parameters and not always need all of them.
You can also adapt it to method invocation.
It also increases readability a lot.
public class BigObject
{
// public getters
// private setters
public static class Buider
{
private A f1;
private B f2;
private C f3;
private D f4;
private E f5;
public Buider setField1(A f1) { this.f1 = f1; return this; }
public Buider setField2(B f2) { this.f2 = f2; return this; }
public Buider setField3(C f3) { this.f3 = f3; return this; }
public Buider setField4(D f4) { this.f4 = f4; return this; }
public Buider setField5(E f5) { this.f5 = f5; return this; }
public BigObject build()
{
BigObject result = new BigObject();
result.setField1(f1);
result.setField2(f2);
result.setField3(f3);
result.setField4(f4);
result.setField5(f5);
return result;
}
}
}
// Usage:
BigObject boo = new BigObject.Builder()
.setField1(/* whatever */)
.setField2(/* whatever */)
.setField3(/* whatever */)
.setField4(/* whatever */)
.setField5(/* whatever */)
.build();
You can also put verification logic into Builder set..() and build() methods.

There is a pattern called as Parameter object.
Idea is to use one object in place of all the parameters. Now even if you need to add parameters later, you just need to add it to the object. The method interface remains same.

You could create a class to hold that data. Needs to be meaningful enough though, but much better than using a map (OMG).

Code Complete* suggests a couple of things:
"Limit the number of a routine's parameters to about seven. Seven is a magic number for people's comprehension" (p 108).
"Put parameters in input-modify-output order ... If several routines use similar parameters, put the similar parameters in a consistent order" (p 105).
Put status or error variables last.
As tvanfosson mentioned, pass only the parts of a structured variables ( objects) that the routine needs. That said, if you're using most of the structured variable in the function, then just pass the whole structure, but be aware that this promotes coupling to some degree.
* First Edition, I know I should update. Also, it's likely that some of this advice may have changed since the second edition was written when OOP was beginning to become more popular.

Using a Map is a simple way to clean the call signature but then you have another problem. You need to look inside the method's body to see what the method expects in that Map, what are the key names or what types the values have.
A cleaner way would be to group all parameters in an object bean but that still does not fix the problem entirely.
What you have here is a design issue. With more than 7 parameters to a method you will start to have problems remembering what they represent and what order they have. From here you will get lots of bugs just by calling the method in wrong parameter order.
You need a better design of the app not a best practice to send lots of parameters.

Good practice would be to refactor. What about these objects means that they should be passed in to this method? Should they be encapsulated into a single object?

Create a bean class, and set the all parameters (setter method) and pass this bean object to the method.

Look at your code, and see why all those parameters are passed in. Sometimes it is possible to refactor the method itself.
Using a map leaves your method vulnerable. What if somebody using your method misspells a parameter name, or posts a string where your method expects a UDT?
Define a Transfer Object . It'll provide you with type-checking at the very least; it may even be possible for you to perform some validation at the point of use instead of within your method.

I would say stick with the way you did it before.
The number of parameters in your example is not a lot, but the alternatives are much more horrible.
Map - There's the efficiency thing that you mentioned, but the bigger problem here are:
Callers don't know what to send you without referring to something
else... Do you have javadocs which states exactly what keys and
values are used? If you do (which is great), then having lots of parameters
isn't a problem either.
It becomes very difficult to accept different argument types. You
can either restrict input parameters to a single type, or use
Map<String, Object> and cast all the values. Both options are
horrible most of the time.
Wrapper objects - this just moves the problem since you need to fill the wrapper object in the first place - instead of directly to your method, it will be to the constructor of the parameter object.
To determine whether moving the problem is appropriate or not depends on the reuse of said object. For instance:
Would not use it: It would only be used once on the first call, so a lot of additional code to deal with 1 line...?
{
AnObject h = obj.callMyMethod(a, b, c, d, e, f, g);
SomeObject i = obj2.callAnotherMethod(a, b, c, h);
FinalResult j = obj3.callAFinalMethod(c, e, f, h, i);
}
May use it: Here, it can do a bit more. First, it can factor the parameters for 3 method calls. it can also perform 2 other lines in itself... so it becomes a state variable in a sense...
{
AnObject h = obj.callMyMethod(a, b, c, d, e, f, g);
e = h.resultOfSomeTransformation();
SomeObject i = obj2.callAnotherMethod(a, b, c, d, e, f, g);
f = i.somethingElse();
FinalResult j = obj3.callAFinalMethod(a, b, c, d, e, f, g, h, i);
}
Builder pattern - this is an anti-pattern in my view. The most desirable error handling mechanism is to detect earlier, not later; but with the builder pattern, calls with missing (programmer did not think to include it) mandatory parameters are moved from compile time to run time. Of course if the programmer intentionally put null or such in the slot, that'll be runtime, but still catching some errors earlier is a much bigger advantage to catering for programmers who refuse to look at the parameter names of the method they are calling.
I find it only appropriate when dealing with large number of optional parameters, and even then, the benefit is marginal at best. I am very much against the builder "pattern".
The other thing people forget to consider is the role of the IDE in all this.
When methods have parameters, IDEs generate most of the code for you, and you have the red lines reminding you what you need to supply/set. When using option 3... you lose this completely. It's now up to the programmer to get it right, and there's no cues during coding and compile time... the programmer must test it to find out.
Furthermore, options 2 and 3, if adopted wide spread unnecessarily, have long term negative implications in terms of maintenance due to the large amount of duplicate code it generates. The more code there is, the more there is to maintain, the more time and money is spent to maintain it.

This is often an indication that your class holds more than one responsibility (i.e., your class does TOO much).
See The Single Responsibility Principle
for further details.

If you are passing too many parameters then try to refactor the method. Maybe it is doing a lot of things that it is not suppose to do. If that is not the case then try substituting the parameters with a single class. This way you can encapsulate everything in a single class instance and pass the instance around and not the parameters.

... and Bob's your uncle: No-hassle fancy-pants APIs for object creation!
https://projectlombok.org/features/Builder

Related

How to create a HashMap with methods as values?

I am working a small program which can receive several commands. Each of these commands should cause different methods to run. I was thinking that if there were a way to put all the methods into a HashMap and invoke them directly by getting the value paired with the command Key instead of using if statements, it could make things much simpler but as far as I understand this is not possible since methods aren't treated as objects in Java. Still, it will be educative to find out if there is a way to do this.
Methods aren't objects (at least mostly not), but there is a concept that matches what you want: the functional interface, which is defined as an interface that has exactly one abstract method. Two out-of-the-box candidates are Runnable, which takes no parameters, and Consumer, which takes a single parameter and might be the best option if you want to pass in some kind of input (like a Scanner). (If you also want a configurable output, BiConsumer taking a Scanner and a PrintWriter might be suitable.)
Java has a convenience feature called method references that can automatically transform a method into an instance of a functional interface. Put together, it might look like this:
Map<String, Consumer<Scanner>> commands = new HashMap<>();
...
commands.put("foo", someCommand::go); // where someCommand is a variable with a go(Scanner) method
commands.put("bar", new OtherCommand());
commands.put("hello", unused -> { System.out.println("Hello!"); });
...
String commandName = scanner.next();
commands.get(commandName).accept(scanner);
This is not a good idea, make methods as hashmap value don't satisfied shell command complex scene, maybe you can use Runnable Object as value.
Another solution, you can use Spring Shell.
#ShellMethod("commandName")
public String doSomething(String param) {
return String.format("Hi %s", param);
}

Side effects in Java methods

This might be a trivial question, but I need some clarification...
There is a book called Clean Code that says that our methods should be small, preferably up to 5-10 lines long. In order to achieve that we need to split our methods into smaller ones.
For instance, we may have someMethod() shown below. Let's say, modification of 'Example' takes 5 lines and I decide to move it into a separate method, modify 'Example' there and return it back to someMethod(). By doing this, someMethod() becomes smaller and easier to read. That's good, but there is a thing called "side effects" which says that we shouldn't pass an object to another method and modify it there. At least, I was told that it's a bad idea ) But I haven't seen anything prohibiting me from doing so in Clean Code.
public Example someMethod() {
// ... different lines here
Example example = new Example();
example = doSomethingHere(example, param1, param2, ...);
// ... different lines here
return example;
}
private Example doSomethingHere(Example example, 'some additional params here') {
// ... modify example's fields here ...
return example;
}
So, am I allowed to split the methods this way or such a side effect is prohibited and instead I should deal with a rather long-line method that definitely breaks Clean Code's rules talking about short methods?
UPDATED (more specific name for the sub-method)
public Example someMethod() {
// ... different lines here
Example example = new Example();
example = setExampleFields(example, param1, param2, ...);
// ... different lines here
return example;
}
private Example setExampleFields(Example example, 'some additional params here') {
// ... modify example's fields here ...
return example;
}
As JB Nizet commented, it's not actually a side effect if it's the only effect, so any blanket statement that "all side effects are bad" doesn't apply here.
Still, the main question stands: Is this (side) effect okay?
Talking about the principles first, side effects are, in general, dangerous for two reasons:
they make concurrency more difficult
they obscure/hide information
In your example, there is some information that is hidden. You could call this a potential side effect, and it can be exposed with a question: "Does this doSomethingHere method create a new object or modify the one I pass in?"
The answer is important, and even more so if it's a public method.
The answer should be trivial to find by reading the doSomethingHere method, especially if you're keeping your methods 'clean', but the information is nonetheless hidden/obscured.
In this specific case, I would make doSomethingHere return void. That way there's no potential for people to think that you've created a new object.
This is just a personal approach - I'm sure that plenty of developers say you should return the object you modify.
Alternatively, you can pick a 'good' method name. "modifyExampleInPlace" or "changeSomeFieldsInPlace" are pretty safe names for your specific example, imo.
we shouldn't pass an object to another method and modify it there.
Who says that? That is actually a good practice in order to split your function in a way that forms a "recipe" and have specific functions that know exactly how to populate your object properly.
What is not recommended (and probably the source where you got your recommendation misunderstood this rule) is defining a public API and modify the arguments. Users appreciate not having their arguments modified as it leads to less surprises. An example of that is passing arrays as arguments to methods.
When you define an object and pass it to an other method, method itself can modify the content of the object therein which may be unwanted in some cases. This is because you pass the reference(shallow copy) of the object to that method and method can modify that object.For example when you pass an Array, Arrays are objects, to a method, method can change the content of the Array which may not be what the caller method expects.
public static void main(String[] args){
int[] arr= {1,2,3,4};
y(arr);
//After the method arr is changed
}
public void y(int[] comingArray){
comingArray[0] = 10;
}
To make sure the values of Array cannot be changed, deep copy of the Array should be sent to method which is another story
However this is not the case when you use primite types(int, float etc.)
public static void main(String[] args){
int a= 1
y(a);
//After the method a is not changed
}
public void y(int comingInt){
comingInt = 5;
}
Due to the nature of the Objects, you should be carefulTo learn more about shallow copy and deep copy https://www.cs.utexas.edu/~scottm/cs307/handouts/deepCopying.htm

How to name a variable that is a copy of a parameter?

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.

Generics - Create data on the fly

This is a complicated question which i will find hard to explain so i appologise in advance.
Imagine an application that invokes another projects methods. I need a way of generating data to match the parameter list. Obviously if the parameter types are of some class that I have no way of generating then it should fail but if its an int[] and int[][] a List<String> a Map<Integer, String> then it should be possible.
What i am struggling with is a decent approach for solving this. I can get the types of parameters via method.getGenericParameterTypes(); example for the parameter HashMap would be java.util.HashMap<java.lang.String, java.lang.Integer> but there are quite a lot of different possibilities right!
I assume generics has some use here? The only issue with that being I have no control over the code that is being invoked. How can I use one of these types and then generate data for it?
I am sorry for the poor explanation, any help appreciated
Thanks
Here we see an example of a method i want to invoke, I want to record how long it takes to run (this is being done via reflection) however, i need to generate data for the parameters. I need a way of generating data to match
public void someMethod(Param a, Param b, Param c)
{
//some user code I have no control over
}
I think perhaps the question should be why you need to do this. Perhaps if you explained your use/business case, we can provide a cleaner (and easier) solution.
From your very last lines, you are talking about wanting to profile the method. Generally speaking, it is rare to want to profile just one small tiny method in the middle of chain of processing. That being said, I can imagine some convoluted cases where this might occur. However, even at that, it should be a handful of cases that you would be able to code yourself.
If it is a question of actual profiling, but you are not sure how to do it, and consequently feel that the only way is to call each method individually so you can "wrap" it with a start/stop timer, I would strongly recommend looking into AOP. Both Spring and AspectJ are great for AOP, with AspectJ able to do byte-weaving that Spring is unable to accomplish.
Consequently, with AspectJ you would be able to create your own profiling timer classes and weave them into the byte-code at compile time and then run your standard tests, but visualize all the profiling info that you want/need on a per-method basis.
And best of all, it would avoid you needing to come up with some convoluted scheme for producing random test data that isn't really relevant to the method being tested.
Sounds like a horrible problem.
If you have the class[] that represents the parameter types of the method then can't you create a new instance of each and pass that as the arguments list to the method? This is untested:
Class[] parameterTypes = method.getGenericParameterTypes();
Object[] args = new Object[parameterTypes.length];
for (int i=0; i < parameterTypes.length; i++) {
args[i] = parameterTypes[i].newInstance(); // assuming the classes can be instantiated without params
}
method.invoke(obj, args); // I assume you've instantiated the object already

Why does java/javascript/python force the use of () after a method name, even if it takes no arguments?

One of my most common bugs is that I can never remember whether something is a method or a property, so I'm constantly adding or removing parentheses.
So I was wondering if there was good logic behind making the difference between calling on an object's properties and methods explicit.
Obviously, it allows you to have properties and methods that share the same name, but I don't think that comes up much.
The only big benefit I can come up with is readability. Sometimes you might want to know whether something is a method or a property while you're looking at code, but I'm having trouble coming up with specific examples when that would be really helpful. But I am a n00b, so I probably just haven't encountered such a situation yet. I'd appreciate examples of such a situation.
Also, are there other languages where the difference isn't explicit?
Anyways, if you could answer, it will help me be less annoyed every time I make this mistake ^-^.
UPDATE:
Thanks everyone for the awesome answers so far! I only have about a week's worth of js, and 1 day of python, so I had no idea you could reference functions without calling them. That's awesome. I have a little more experience with java, so that's where I was mostly coming from... can anyone come up with an equally compelling argument for that to be the case in java, where you can't reference functions? Aside from it being a very explicit language, with all the benefits that entails :).
All modern languages require this because referencing a function and calling a function are separate actions.
For example,
def func():
print "hello"
return 10
a = func
a()
Clearly, a = func and a = func() have very different meanings.
Ruby--the most likely language you're thinking of in contrast--doesn't require the parentheses; it can do this because it doesn't support taking references to functions.
In languages like Python and JavaScript, functions are first–class objects. This means that you can pass functions around, just like you can pass around any other value. The parentheses after the function name (the () in myfunc()) actually constitute an operator, just like + or *. Instead of meaning "add this number to another number" (in the case of +), () means "execute the preceding function". This is necessary because it is possible to use a function without executing it. For example, you may wish to compare it to another function using ==, or you may wish to pass it into another function, such as in this JavaScript example:
function alertSomething(message) {
alert(message);
}
function myOtherFunction(someFunction, someArg) {
someFunction(someArg);
}
// here we are using the alertSomething function without calling it directly
myOtherFunction(alertSomething, "Hello, araneae!");
In short: it is important to be able to refer to a function without calling it — this is why the distinction is necessary.
At least in JS, its because you can pass functions around.
var func = new Function();
you can then so something like
var f = func
f()
so 'f' and 'func' are references to the function, and f() or func() is the invocation of the function.
which is not the same as
var val = f();
which assigns the result of the invocation to a var.
For Java, you cannot pass functions around, at least like you can in JS, so there is no reason the language needs to require a () to invoke a method. But it is what it is.
I can't speak at all for python.
But the main point is different languages might have reasons why syntax may be necessary, and sometimes syntax is just syntax.
I think you answered it yourself:
One of my most common bugs is that I can never remember whether something is a method or a property, so I'm constantly adding or removing parentheses.
Consider the following:
if (colorOfTheSky == 'blue')
vs:
if (colorOfTheSky() == 'blue')
We can tell just by looking that the first checks for a variable called colorOfTheSky, and we want to know if its value is blue. In the second, we know that colorOfTheSky() calls a function (method) and we want to know if its return value is blue.
If we didn't have this distinction it would be extremely ambiguous in situations like this.
To answer your last question, I don't know of any languages that don't have this distinction.
Also, you probably have a design problem if you can't tell the difference between your methods and your properties; as another answer points out, methods and properties have different roles to play. Furthermore it is good practice for your method names to be actions, e.g. getPageTitle, getUserId, etc., and for your properties to be nouns, e.g., pageTitle, userId. These should be easily decipherable in your code for both you and anyone who comes along later and reads your code.
If you're having troubles, distinguishing between your properties and methods, you're probably not naming them very well.
In general, your methods should have a verb in them: i.e. write, print, echo, open, close, get, set, and property names should be nouns or adjectives: name, color, filled, loaded.
It's very important to use meaningful method and property names, without it, you'll find that you'll have difficulty reading your own code.
In Java, I can think of two reasons why the () is required:
1) Java had a specific design goal to have a "C/C++ like" syntax, to make it easy for C and C++ programmers to learn the language. Both C and C++ require the parentheses.
2) The Java syntax specifically requires the parentheses to disambiguate a reference to an attribute or local from a call to a method. This is because method names and attribute / local names are declared in different namespaces. So the following is legal Java:
public class SomeClass {
private int name;
private int name() { ... }
...
int norm = name; // this one
}
If the () was not required for a method call, the compiler would not be able to tell if the labeled statement ("this one") was assigning the value of the name attribute or the result of calling the name() method.
The difference isn't always explicit in VBA. This is a call to a Sub (i.e. a method with no return value) which takes no parameters (all examples are from Excel):
Worksheets("Sheet1").UsedRange.Columns.AutoFit
whereas this is accessing an attribute then passing it as a parameter:
MsgBox Application.Creator
As in the previous example, parentheses are also optional around parameters if there is no need to deal with the return value:
Application.Goto Worksheets("Sheet2").Range("A1")
but are needed if the return value is used:
iRows = Len("hello world")
Because referencing and calling a method are two different things. Consider X.method being the method of class X and x being an instance of X, so x.method == 'blue' would'nt ever be able to be true because methods are not strings.
You can try this: print a method of an object:
>>> class X(object):
... def a(self):
... print 'a'
...
>>> x=X()
>>> print x.a
<bound method X.a of <__main__.X object at 0x0235A910>>
Typically properties are accessors, and methods perform some sort of action. Going on this assumption, it's cheap to use a property, expensive to use a method.
Foo.Bar, for example, would indicate to me that it would return a value, like a string, without lots of overhead.
Foo.Bar() (or more likely, Foo.GetBar()), on the other hand, implies needing to retrieve the value for "Bar", perhaps from a database.
Properties and methods have different purposes and different implications, so they should be differentiated in code as well.
By the way, in all languages I know of the difference in syntax is explicit, but behind the scenes properties are often treated as simply special method calls.

Categories

Resources