So, say I've got lots of values and flags passed into my program from the command line, all stored as variables in some configuration object, config. These variables default to null if they are not provided by the user.
I've then got some other object, say an instance of Dog, which has lots of methods. Depending on the value of a specific command line argument, I may or may not want to call a specific method, possibly passing the argument value to the method.
At the moment I'm doing that like this:
Dog dog = new Dog();
if (config.argumentA != null) {
dog.methodA(config.argumentA);
}
if (config.argumentB != null) {
dog.methodB(config.argumentB);
}
if (config.boolArgument) {
dog.methodC();
}
// ... ... ...
if (config.argumentZ != null) {
dog.methodZ(config.argumentZ);
}
Now I've tried to look for a more elegant way of doing this, since this feels very dirty, but Google and Java jargon have me stumped.
I'm imagining making a map from the arguments' names to the function names, then looping through, checking each argument's value and calling the corresponding method. Does such a mapping exist in Java? Is there any way to do this nicely, or am I going about the problem completely wrong?
P.S.: I'm a bit of a beginner with both Java and problems like this, so pls be gentle :)
Actually this question relates to the programming practices. So like Alan Kay said OOP is basically message passing. Thus your code should not be making these decisions but rather passing this info to some other method of some other class, till the time it's actually needed. Now if you couple this concept with different Design patterns you'll get an elegant piece of code.
Also it's difficult to suggest a particular solution to a problem as abstract as your's.
I have searched for this question and found a few answers but have not really found what I am looking for.
I call Java using JNI from C++ and set a Java object's fields one by one. Something like below:
jobject jSomeObject = (jobject) JVM_ENV->CallObjectMethod(myObj, getObjMethodID, "");
JVM_ENV->CallVoidMethod(jSomeObject , setMethodID1, SomeIntVal);
JVM_ENV->CallVoidMethod(jSomeObject , setMethodID2, SomeStringVal);
All parameters inside the jSomeObject are set one by one like this. And you see that there are multiple JNI calls going on which is expensive. What I am thinking is, if there is a way that I set all the parameters in the native environment and send the object just once to avoid multiple JNI calls.
Some of the posts says that it is not possible to pass a custom object to JNI. Can I do it ?
Edit:
Above calls changed to something:
jobject jSomeObject = (jobject) JVM_ENV->CallObjectMethod(myObj, getObjMethodID, "");
someClass obj = new someClass();
obj.setMethod1(someInvVal);
obj.setMethod2(someStringVal); // so on...
JVM_ENV->CallVoidMethod(jSomeObject , setMethodID1, obj);
No: You can only call methods and constructors and get and set fields that are defined in Java.
Yes: You can possibly define additional classes and methods in Java that will do what you need in one call. For example, myObj:getObjMethodID seems to be a factory method. You could add a method overload that takes all the values you want to initialize the created object with.
In general, if you can make things powerful in Java, the tasks done in JNI will be simpler.
may I ask how to actually access the elements of an Object. My intention is to print out any object class, so I'm using
String x = ReflectionToStringBuilder.reflectionToString(obj)
with some style and modification, I'm able to make the "x" to become
[companyid=KLK,descp=KLK Kepong,reqbio=1,basedcountry=MY,processingfee=1.0]
but my problem come which is, IF there is another object (arraylist) inside that "obj" , the ReflectionToStringBuilder won't able to change that object to string and instead it become something like
[companyid=KLK,descp=KLK Kepong,banks=[my.sdinx.sdimngapi.peak.data.NP_CompaniesBanks#12d41a05]]
How can I actually access this
banks=[my.sdinx.sdimngapi.peak.data.NP_CompaniesBanks#12d41a05]
and change it to become like
[companyid=KLK,descp=KLK Kepong,banks=[bankid=MBB,descp=Maybank]]
I can't find a way to access it because my function accept Object so it won't know which custom class its accepting.
#Override
public void insertAuditLogDet(int recid, Object obj, Object obj2) throws
SQLException { "processing the changed and insert into db" }
Implement toString() method in NP_CompaniesBanks class. That should solve it. I just tried it.
Simple: you need to enhance your generic "dumper" method to do a "recursive" decent.
In other words: you apply your method on the fields that you find in your object.
There is nothing magic about this; it is "just work". But of course: complicated work; as you might have to apply certain heuristics; for example to turn a "list" into a string that uses [ to ] wrap around the elements of the list.
I would like to save some work on my app, is it possible to get the string, for example "level1" and then use the corresponding function, which would be level1();? my main point is not to make a huge switch-case statement, but only make a few level functions in a storage class, and whenever you level up, the string would change to "level" + number where number is the int, so lets say that right now you are in level 10, the function that would run is level10();
I hope i explained it clearly.. sorry if not.. hope you get the idea!
Thanks!
I believe you want to call a method at runtime using its name as a string.
You can do it via reflection.
Class.getMethod(String methodName, Class... parameterTypes)
Don't think of this in terms of method names, unless you want to muck around with reflection (you don't want to, and it's not necessary).
If you really do need to convert strings to method calls – and that's a big "if" – create a Map<String, Foo> where Foo implements some "callable"-like interface. Then a string-to-method lookup is simply:
Map<String, Foo> commands = /* ... */;
Foo foo = commands.get("level42");
foo.bar();
It really sounds like you should just have a
void setLevel(int level)
call. That can feel free to ignore (say) levels 11-14 or whatever... but it would be very ugly to have separate methods and invoke them by name. You can do so with reflection, but you should think about other options first.
Please see the top answer to this post:
Java dynamic function calling
I would also recommend following their advice regarding structure, to create a more object-oriented solution instead of using reflection.
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.