A professor of mine once said that the following code should never be done:
System.out.println(object.toString());
He said (and I believe cited "Effective Java") it causes a double call. Since the print statement calls the toString method of an object, it would be less efficient to have the toString method called twice. The preferred method would be to just use:
System.out.println(object);
Obviously this way looks better in code and would save time. I will always do it like this no matter what, but my question is "Is this actually more EFFICIENT?". In looking through the PrintStream documentation, the print method has been overloaded to take a String as the parameter (which would be the case if the toString method were called first). I am not seeing where that version of the print method calls the toString method of the inputted parameter and I don't believe it would make sense for it to do that.
Also, sorry if this is a duplicate. I couldn't find any topics on it.
Your examples call two different methods in PrintStream. Both call toString() at most once.
The first method calls println(String x), which does not call
x.toString() itself.
The second method calls println( Object x ), which leads to a call of
x.toString() if x is not null.
However, there is a potential advantage to using System.out.println(object). If object is null, this prints "null". The other statement throws a NullPointerException.
No, it is not more efficient -- precisely because of the overload that you mentioned. Moreover, a call of toString on a String is extremely quick, so even without an overload the difference would not be measurable.
However, your professor is right about not making the call like System.out.println(object.toString());, but the reason is different: since the call is unnecessary, the readers of your code may get confused.
in a multithreading environment calling System.out.println is actually bad enough, even much worst than a unneeded call to toString. The "problem" exist because you have a synchorized call inside "println":
public void println() {
newLine();
}
private void newLine() {
try {
synchronized (this) {
ensureOpen();
...
}
So, if you are trying to write efficient java, you could start by avoiding it. As an alternative you could use any of the different logging mechanism, e.g. http://www.slf4j.org/
Related
For example:
public class Demo{
public String getReflectString() {
return "string from reflect";
}
public String reflectMethod() throws Exception {
Method method = ReflectCase.class.getMethod("getReflectString");
return (String) method.invoke(this);
}
}
Method Demo#getReflectString called by reflection,and I wanna find a way to get all the methods in the program that are called this way.
I came up with a solution that has not yet been implemented.
Read the contents of the class file, start from the instruction, find the Method#invoke
instruction, and then look back to find the instance that calls the method, and then get the instance corresponding Class and MethodName.
However, this method has a problem, if Class or MethodName or even Method are passed as a parameter, it is difficult to find the corresponding content.
On this basis, think of ways to improve, traverse all the methods, check the instructions of the method. If got Method#invoke instruction in method A(), and Class and MethodName are passed in as parameters, record method A() and the order of parameters. In the following check, if there is a method call A(), you can get the value passed to method A() Parameters, to obtain the required value.
However, this solution requires traversing the entire program's instructions, which can be very time-consuming when the program is very large. If method call too many levels, the implementation of the algorithm can be quite complicated. So would like to ask, the feasibility of this idea, or is there any better way to solve the problem.
Thanks in advance.
In my java code I need to call one method inside the other. The argument passed to suspendUserTestList must not be null. So the very simple question is where I must to check for null case: before passing the value or inside the second method?
Here are my methods:
public String suspendTest(Integer locationId, Integer userId) {
testManager.suspendUserTestList(userTestList, SUSPENDED_TEST_FREQUENCY, usersTestsSuspenSession);
}
public void suspendUserTestList(List<UserTest> userTestList, Integer frequency, Session session) throws MonitorUsException {
if (userTestList == null) {
throw new MonitorUsException("Error");
}
}
Short answer will be Depends.
Long answer is .......
After looking at your method implementation, you are throwing the exception if it is null. So you have to call the method before checking to receive that exception.
If you check before calling the method, you won't receive any exception and it just skip the call to that method and proceeds further.
If you are fine with not calling even if it is null, check for null and then only call the method.
It's definitely a good idea to check the inputs of every method. So if your suspendUserTestList() method expects a non-null parameter, it should check that the parameter is indeed non-null before using it.
It makes your method more self-contained and less dependent on its calling environment. It's also easy to read and to test in isolation.
Whether you then also check in the caller is not so straightforward to answer, it depends on a lot of factors. I'd go with whatever looks cleaner.
Generally speaking
Generally, you want to check for null where you actually use the object's methods or properties.
However if the calling method knows that the called method will not check for null (when you use a library for instance, you have no control of how the object you give will be used, but by inspecting the code you may see that no null check is made), then you have to either check for null or catch NullPointerExceptions.
In any case, you must make sure to catch the possible NullPointerExceptions in a given layer of your application (for instance a level where you can provide the information to the user, if there is a UI).
Particular case
In your own particular case, your two methods are public. Because both can be called from outside, you have to make sure that the null check is made at the lowest level (suspendUserTestList), because you may start to call the suspendUserTestList method from other places in your code. By putting the null check in suspendUserTestList, you make sure that all other possible future calls to this method will have the same null check logic.
There is no fixed rule, both places can be valid. Common sense is to do it in the called method so you write the logic ones and not in all places where you use the method. Probably throw an IllegalArgumentException to not add new types for a common case.
It's definitely ok to check inside the public method (it's called "precondition"). As for checking before the call, it depends how you are using this userTestList field. Probably it was initialized in the constructor (like userTestList = new ArrayList<>()) and never reassigned. Then no need to check it anywhere (better to declare it as final). On the other hand it can be passed in some setter like this:
public void setUserTestList(List<UserTest> list) {
this.userTestList = list;
}
In this case it's much better to add one more check in the setter. In any case it's better to do the checks as early as possible.
Lets say you have some random class called Dude, and you have some private instance variables and you have some get methods and a compareTo method to say if one instance of the class has the same variables as another instance of the class and that's pretty much it. Well, lets say in some driver class, you make two Dude objects, and you call them d1 and d2.
Well, now you wanna compare the two and see if they have the same instance data, so you'd call d1.compareTo(d2);
Now, my question is, when creating the compareTo method inside the dude class, you pass it one object as a parameter and the other one.....?
I'm thinking it would go something like this:
public boolean compareTo(Dude d){
if (this.getArbitraryVariable() == d.getArbitraryVariable()) return true
and so on.
But for that to work, you would have no clue what the currently executing object is, and the only logical explaination I can think of is that the "." operator makes whatever is to the left of it, the current executing object in the class. Is that right or no?
That is not quite the correct intuition.
When you write d1.compareTo(d2);, this compiles down to something closer to compareTo(d1,d2).
That is, when you call a method on an object, you basically pass the object as the first parameter implicitly.
When you are inside the method, you use the keyword this to refer to the implicit object that was passed to the method.
The dot operator not only gives you the current executing object , it can also give you the current executing class, which is how you use static methods and static variables.
For ex :-
staticClass.staticMethod();
Also you can use the dot operator for chaining. For ex
String finalValue=input.replaceAll("numbers","alphabets").substring(0,`32).trim();
Following this tutorial:
http://developer.android.com/training/notepad/notepad-ex2.html
In Step 2, this method gets called:
registerForContextMenu(getListView());
which is a public method of Activity. Now, I'm a bit of a Java newbie here - I thought if you wanted to call an instance method of a superclass you needed to preface it with this. E.g.
this.registerForContextMenu(getListView());
Is it just a style thing here? Is there any difference between
this.registerForContextMenu
and simply
registerForContextMenu
No, there is no difference.
You don't have to use this., but it is often done anyway to make the code clearer.
For one thing, it makes it easy to tell if a method is static or not if you use the convention of calling instance methods like this:
this.registerForContextMenu()
and static methods like this:
ClassName.staticRegisterForContextMenu()
you do not have to use this. If you ommit it it is assumed you called method in this scope. One particular example when this may help could be i.e.:
Boolean someVar;
public function setMe( Boolean someVar ) {
this.someVar = someVar;
}
In this case, w/o this you would get the error.
To call a method of superclass either you need object of superclss or keyword super .
eg.
superObject.superclassMethod();
super.superclassMethod();
this is a reference of the current object. this can be used to call method of a class in which it is used. this can never be used to call a superclass method.
As for
this.registerForContextMenu()
and
registerForContextMenu()
no such difference. you can use either of them.
Both ways are correct for calling a method on the current (this) instance of the class. Non private methods are inherited from super classes, so you can use the same syntax to call such methods.
In a recent question, someone asked about static methods and one of the answers stated that you generally call them with something like:
MyClassName.myStaticMethod();
The comments on that also stated that you could also call it via an object with:
MyClassName myVar;
myVar.myStaticMethod();
but that it was considered bad form.
Now it seems to me that doing this can actually make my life easier so I don't have to worry about what's static or not (a).
Is there some problem with calling static functions via an object? Obviously you wouldn't want to create a brand new object just to call it:
Integer xyzzy;
int plugh = xyzzy.parseInt ("42", 10);
But, if you already have an object of the desired type, is there a problem in using it?
(a) Obviously, I can't call a non-static method with:
MyClassName.myNonStaticMethod();
but that's not the issue I'm asking about here.
In my opinion, the real use case that makes this so unreadable is something like this. What does the code below print?
//in a main method somewhere
Super instance = new Sub();
instance.method();
//...
public class Super {
public static void method() {
System.out.println("Super");
}
}
public class Sub extends Super {
public static void method() {
System.out.println("Sub");
}
}
The answer is that it prints "Super", because static methods are not virtual. Even though instance is-a Sub, the compiler can only go on the type of the variable which is Super. However, by calling the method via instance rather than Super, you are subtly implying that it will be virtual.
In fact, a developer reading the instance.method() would have to look at the declaration of the method (its signature) to know which method it actually being called. You mention
it seems to me that doing this can actually make my life easier so I don't have to worry about what's static or not
But in the case above context is actually very important!
I can fairly confidently say it was a mistake for the language designers to allow this in the first place. Stay away.
The bad form comment comes from the Coding Conventions for Java
See http://www.oracle.com/technetwork/java/codeconventions-137265.html#587
The reason for it, if you think about it, is that the method, being static, does not belong to any particular object. Because it belongs to the class, why would you want to elevate a particular object to such a special status that it appears to own a method?
In your particular example, you can use an existing integer through which to call parseInt (that is, it is legal in Java) but that puts the reader's focus on that particular integer object. It can be confusing to readers, and therefore the guidance is to avoid this style.
Regarding this making life easier for you the programmer, turn it around and ask what makes life easier on the reader? There are two kinds of methods: instance and static. When you see a the expression C.m and you know C is a class, you know m must be a static method. When you see x.m (where x is an instance) you can't tell, but it looks like an instance method and so most everyone reserves this syntax for instance methods only.
It's a matter of communication. Calling a method on an instance implies you're acting on/with that particular instance, not on/with the instance's class.
It might get super confusing when you have an object that inherits from another object, overriding its static method. Especially if you're referring to the object as a type of its ancestor class. It wouldn't be obvious as to which method you're running.