Better to abstract out detail or use a setter? [closed] - java

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 3 years ago.
Improve this question
In terms of best practices, suppose I have this code:
public class ClassObject {
private int someNumber;
public void setSomeNumber(int x){
this.someNumber = x;
}
public int getSomeNumber(int x){
return this.someNumber;
}
//Should I even use this?
public void decreaseSomeNumber(){
--this.someNumber;
}
}
public void doSomeStuff(ClassObject instance){
// do some things
instance.decreaseSomeNumber(); //A
instance.setSomeNumber(instance.getSomeNumber() - 1); //B
}
I am wondering if either lines A or B are code smells. I think decreaseSomeNumber() is likely a redundant/useless function since I can just do instance.setSomeNumber(instance.getSomeNumber() - 1); everwhere.
On the other hand, it seems slightly more verbose doing instance.setSomeNumber(instance.getSomeNumber() - 1). What is the cleanest and good code design between A and B?

If you have a multithreaded environment, having (A) a decreaseSomeNumber method is worth it, however, you should make it threadsafe. Otherwise (B) two parallel threads might try to decrease the value at the same time, resulting in just a single decrease operation if they overlap.
That being said, it's typically hard work to really make code threadsafe, and in simple cases, occasional glitches might not matter. However, occasional is the keyword here: If you ever run into these, reproducing the problem will be horribly hard.

In terms of best practises you must avoid when is possible the form
public void decreaseSomeNumber(){
--this.someNumber;
}
and prefer the standard getters and setters.
But in some cases you need to decrease the value of a variable,
if this thing is occasional is good to use getters and setters
instance.setSomeNumber(instance.getSomeNumber() - 1);
instead in the case you need decreasing the a variable repeatedly (ex. A withdraw in a bank account) using only one method is not bad, but it must be defined like
public void decreaseSomeNumber(int many){
this.someNumber -= many;
}
in this way you are making a code more reusable, and this is good
P.S. the B way is more simple to syncronize in multi-threading enviroments

I would say it depends on more specific details, but I would be probably in favour of decreaseSomething.
With the getter and setter, you implicitly assume that:
The user of the API implements some (albeit trivial) computation.
The computation is performed at the time of the request.
The caller handles to concurrency-related issues on their own.
The (1) is rather a philosophical problem, although it might lead to errors caused by inadvertence, like calling get and set on two different objects.
The (2) can be a practical problem. Maybe you want to use the object from multiple threads. And maybe you don't need the number often, but you need to change it often. I believe that one could come up with some optimizations based on LongAdder or LongAccumulator or AtomicInt, which can optimize some highly concurrent places. With decreaseSomething, you can do it inside the class implementation. With getters and setters, you would need to somehow replace all occurences of x.setSomething(x.getSomething() + 1) by something else. That does not look like a proper encapsulation…
The (3) depends on your objective. Some people just make thread-unsafe code and claim it is programmer's responsibility to handle locks where needed, which can be OK. Sometimes, there might be a demand for thread-safe code. With getter and setter, you would need to use some locking scheme every time you access the data (which also makes (1) a less philosophical issue). Sometimes, it can be awful. Sometimes, it can be OK, because the caller wants to lock something more than just this one object.
As mentioned on the start of the post, I don't say I would prefer it every time. Maybe there are some cases when I would not go this way.

Edited
I would recommend changing this class as follows:
public class ClassObject {
private final int someNumber;
public ClassObject(int someNumber) {
this.someNumber = someNumber;
}
public int getSomeNumber() {
return someNumber;
}
public ClassObject decreaseSomeNumber() {
return new ClassObject(someNumber - 1);
}
public void doSomeStuff(ClassObject instance) {
//New ClassObject with new someNumber(instance's someNumber is decreased one unit)
ClassObject decreasedNumberClassObject = instance.decreaseSomeNumber();
}
}
I mean, if you wanna make a change in the Class properties(decrease, increase, multiply,...), it must return you, new Object(from the same Class), with the new property.
This code completely follows OOP paradigms. It is thread-safe, immutable and software(code) maintenance will be very high with the help of this approach.

Related

Is it good to call instance attributes using getter and setter? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 1 year ago.
Improve this question
I'm making a battleship java game and throughout the entire process I've used the Point class to store X and Y coordinates. I know how getters and setters work and why we used them, but this specific class has both getters and public attributes so here's my question, what would it be better to use?
p.x or p.getX()
I know it's a good practice to use getters but I'm confused in this case, what should I use?
(to recap, this is about Immutable Objects vs changing primitive position values directly)
I have to counter #rzwitserloot's answer. He has provided three problematic classes:
The first one, the Lombok one, is either also immutable, or using #NonFinal or #PackagePrivate annotations, thus using (creating/allowing) unchecked getters and setters. So when it comes to how safe the code is, that either has the problems of immutability, or it's simply the same level as (directly accessible) public member variables.
The second one, the record, is shallowly immutable. That means that any change to the position cannot be done to the Point itself, but each time a new instance of Point has to be created
The third one, very similar to the second one, is a truly immutable class. Same here: any change to the position cannot be done to the Point itself, but each time a new instance of Point has to be created
So what we see here: immutability. If you want to keep your code nice and clean, immutability is nice. Especially for debugging. Immutability is a fine tool for writing clean software. The dream of tinkerers. But for hands-on guys, in some situations, this soon becomes 'overengineering'.
But with regards to performance there are some problems:
For every change to an immutable class, you have to create a copy of that class, with a few changes
It's harder to change only one aspect/value, then change another value later, without creating multiple objects
So, assuming a stupid JVM,
you'd soon run into memory-based performance problems, due to all those objects you need to create
the speed is a horrible lot slower than simply changing the values.
Gladly, the JVM is very smart:
After a short runtime the JIT finds/knows classes that are used and discarded and optimizes that.
Also, access via getters/setters is a lot slower, but the JVM also can take most of that away in most situations.
Also, with the JVM advancing every year, chances are that the optimization/speed will increase further, reducing or maybe even annihilating any disadvantages of the immutable classes. Also, the optimizations will definitely be safer or at least as safe as anything you could design. But can they be as efficient?
BUT there are also cases where the JVM can do neither optimizations. Especially when interfaces/abstract base classes are involved, even method calling can get slower, because addresses of the real targeted methods has to be resolved at runtime, each and every time.
So in the end, it's up to you to test and decide, what approach you want to use.
If this bit of added safety is really worth the 'drop' in performance.
And how much you expect from the future, regarding JVM optimization.
Where the others are right: don't use AWT classes unless you're really using AWT. Better have your own class that you can fit to your needs.
// BIG UPDATE:
One last thing to consider, and IMO the biggest downside to using an immutable Position type:
(WARNING: This example will get more and more ridiculous! But it shows where that strategy leads)
Let's say we have the following Class: class Ship { Position position; }
So we address that position via ship.position
Now, when we want to change the ship's position, we have to change the reference to the position: ship.position = ... (new Position or ship.position.clone(newX,newY) or ship.position.with(newX,newY)
So whenever we want to change the ship's position, and follow the immutability pattern
semi-consequently: we would at least need another getter/setter for Position in Ship
Anything working with positions would also have to know its containing Classes, for example Ship and any and all other things that have a Position and might be computed by the same logic (yes, interfaces, but where does that stop?)
Also you'd have to check every time if the Ship.position is not null...
fully consequently: the Ship should also be immutable, and on any change to its position or any other status, the Ship in the Scenario would be replaced by a muted immutable copy.
Also, the Scenario would have to be replaced on any change. Wow.
Anything working with the ship would also have to know all the References TO the Ship, so it can update those
If the Scenario changes, the Game should also be immutable and its instance has to be replaced.. wait, what?
So we see that there exist a lot of scenarios where immutable Objects are not a good solution
That Point class is an old, obsolete relic that is all sorts of non-idiomatic java. The original mistake is using it in the first place; your code presumably has nothing to do with java.awt, so using a class from within that package was not a great idea. Even if it is, that class is just a mistake at this point, but unfortunately its documentation does not point this out.
Given that the mistake has been made, the question 'which one of these 2 things are better style' is basically moot: Either one is bad.
If you'd have to flip the coin here, go with .getX() which at least looks more idiomatic.
If you have the time, make your own Point class. It should look like:
#Value public class Point {
int x, y;
}
or
public record Point(int x, y) {
}
or
public class Point {
private final int x, y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
#Override public int hashCode() {
return (x * 31) ^ y;
}
#Override public boolean equals(Object other) {
if (other == this) return true;
if (!(other instanceof Point)) return false;
Point p = (Point) other;
return p.x == x && p.y == y;
}
#Override public String toString() {
return String.format("[%d, %d]", x, y);
}
}
Given the wall of text that third one entails, one of the first two options are probably better. The first one uses Project Lombok to avoid the boilerplate, the second one uses a feature you can't really use unless you have Java16 installed.
NB: I am known to contribute to Lombok :)
NB2: The reason java.awt.Point is not going to change is because existing code will have p.x = 5; or whatnot someplace, and thus, changing it like this (making it immutable) would break existing code, which java doesn't do unless there very strong mitigating reasons to do it.
If you have some modification while setting your attribute like hashing or encrypting
, you should make these attribute in private, use getter and setter, else, just make your attribute in public.

In If else branches, what is the preferred approach? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 3 years ago.
Improve this question
I am writing a validation function, which checks a multitude of conditions and returns Success if none of the checks fail. I want to know, what would be the preferred way among two choices and why ?
private ResponseObj validationFunc1(ObjA objA, ObjB objB, ObjC objC){
ResponseObj responseObj = new ResponseObj();
if(condA){
responseObj.setStatus("FAILURE");
responseObj.setMessage("condA message");
return responseObj;
} else if(condB){
responseObj.setStatus("FAILURE");
responseObj.setMessage("condB message");
return responseObj;
} ....
...
}else if(condZ){
responseObj.setStatus("FAILURE");
responseObj.setMessage("condZ message");
return responseObj;
}
responseObj.setStatus("SUCCESS");
responseObj.setMessage("Valid");
return responseObj;
}
private ResponseObj validationFunc2(ObjA objA, ObjB objB, ObjC objC){
if(condA){
return new ResponseObj("FAILURE","condA message");
} else if(condB){
return new ResponseObj("FAILURE","condB message");
} ....
...
}else if(condZ){
return new ResponseObj("FAILURE","condZ message");
}
return new ResponseObj("SUCCESS","Valid");
}
Which of the above 2 functions would be preferred in production code ? If so, does one method has a performance gain over another ?
Or, Am I just mistaken and the compiled code for both the functions will be same ?
Thanks in advance for your answers. If I have asked the same question again, I am very sorry. I did try my best to search for this.
Which of the above 2 functions would be preferred in production code
Neither one.
Good code follows certain rules, especially for Java, nicely formulated in the "Clean Code" book by Robert Martin. Things that clean code strongly advocates against:
high number of parameters (and 2 is consider high already ;-)
doing multiple "things" within one method/class
So, at least for some people, (well written) production code would look much different.
What you could do for example: define an interface Validator, and then put each different validation into its own class implementing that interface. And then "multiple" checks turns into instantiating each of those classes, and putting the objects in some List<Validator> ... when you then iterate, and apply one after the other.
And note: performance doesn't matter here, too. The only thing that matters is how easy to read, understand, and maintain your code is. At least for me, the above ... isn't very good at that, for the reasons stated above.
Performance should be the same. You're making the same amount of comparisons and object creations in both cases.
Approach 1 is generally easier to trace later, especially in complicated functions. At the same time, something like
if (condition) {
// lots of code
// that scrolls and scrolls
// with its own fors and ifs and whiles
} else {
// by the time you're here, you've no idea what the corresponding if() was
}
can often be replaced with
if (!condition) {
return "error";
}
// lots and lots of code
and become more readable in the process. To summarize, there is not really a right answer, use your judgement and pick the variant you feel is easier to understand
The second example probably performs better because it has less method calls. However, it is so negligible that you really need to stop caring about it.
More importantly, the second example is more readable and less prone to bugs. For the first example, you have to worry about where responseObj came from and how corrupted its state may already be before you even get to it.
To review your sample.
Always prefer immutability, so your second approach would be
better.
Returning early the code easy to follow so you don't have to
scroll all the way down.
Returning a new
ResponseObj("SUCCESS","Valid") is not a good structure cause it
would open the gate to be (incorrectly) create a new
ResponseObj("SUCCESS","Failure"). I'd suggest replacing it by an
enum with both fields, which would also make the check for success
easier downstream.
Keep it easy with the args as already pointed out
2nd approach is better, because in 1st approach code is tightly coupled and have repeated lines.
1) For tightly coupled:
If the class provider ResponseObj is third person if they renamed the data members and their respective setters and getters then you also have to change where ever you have implemented.
2) Repeated lines of code:
responseObj.setStatus("FAILURE"); there are so much same lines of code which we can see in every condition, and we dont know how many goes with number of conditions.
Solution: I feel 2nd Apparoach is better, however every thread should create a new object and constructors can be create any numbers as per the required(Overloading) without impacting to existing implemented developers.

Need Example of Poor Encapsulation [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
I want to see an example of reaching directly into the code from a class that uses publicly declared data members to see an example of poor encapsulation so I can understand the good examples of encapsulation in OOP by contrasting with a bad example.(Being told to use encapsulation without a bad example is like being told not to steal without understanding what stealing is to me.) Thanks.
Suppose you have a Counter class that:
Starts with value = 0
Lets you increase the value by one (increment)
Lets you see the current value
A poorly-encapsulated version would directly expose the inner counter value:
class Counter {
public int value;
public Counter() {
this.value = 0;
}
public int increment() {
return ++this.value;
}
}
The problem, of course, is that users of the class can do this:
Counter c = new Counter();
System.out.println(c.value); // 0
c.increment();
System.out.println(c.value); // 1
c.value = 42;
System.out.println(c.value); // 42
Proper encapsulation corrects that:
class Counter {
private int value; // *** Private
public Counter() {
this.value = 0;
}
public int increment() {
return ++this.value;
}
public int getValue() { // *** Accessor
return this.value;
}
}
Now, there's no way¹ for the user of the class to directly set value.
Counter c = new Counter();
System.out.println(c.getValue()); // 0
c.increment();
System.out.println(c.getValue()); // 1
// No equivalent to `c.value = 42` is possible here¹
¹ (without using reflection)
Your question is a useful one, since understanding the reasons that encapsulation is important will help you avoid overgeneralizing the principle as well as help you understand when you've done it adequately.
You can find an example of poor encapsulation here: https://github.com/dotnet/training-tutorials/blob/master/content/csharp/getting-started/encapsulation-oop.md When the class in the example is used by other code to do something mundane, it create problems because the class hasn't been encapsulated. (Other examples might illustrate the problems that are created by poor encapsulation rather than a lack of encapsulation, but I understand you to want an example of the basic idea.)
Many times the problem that is created by not encapsulating your code is that properties and/or objects are updated or deleted when it is a copy of the object that you actually wish to update or delete.
Here are some relevant portions of the linked example. The first quote describes the problem that is created when the class lacks encapsulation:
Notice that in this example, the technique used to print the orders is a while loop that throws away each record as it prints it. This is an implementation detail, and if the collection this loop was working with were properly encapsulated, it wouldn't cause any issues. Unfortunately, even though a locally scoped orders variable is used to represent the collection, the calls to RemoveAt are actually removing records from the underlying Customer object. At the end of the program, both customers have 0 orders. This is not the intended behavior.
The second quote notes that the problem can be "solved" with a different implementation, but avoided altogether with encapsulation:
There are a variety of ways this can be addressed, the simplest of which is to change the while loop to a foreach, but the underlying problem is that Customer isn't encapsulating its Orders property in any way. Even if it didn't allow other classes to set the property, the List type it exposes is itself breaking encapsulation, and allowing collaborators to arbitrarily Remove or even Clear the contents of the collection.
What this example illustrates well is that the need for encapsulation isn't absolute, but it's most certainly a best practice.

How to program if conditionals, and when does one approach become better than the other [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
I am wondering, mostly as an industry standard approach, or as a explicitly best practice approach how would one usually program if conditionals.
I find myself using the first approach below very often, never truly had a problem with it. But I'm still wondering when should either be used.
This is just an example to illustrate what I mean, it shouldn't be taken as the normal complexity of the comparisons usually utilized.
Example
public class Validation {
int x = 5,
y = 10,
z = 100,
a = 1;
public void compare() {
if (x < y) {
// Do Something
if (y < z) {
// Do Something
if (z < a) {
System.out.println("Whatever");
}
}
}
}
public void alternate() {
if (compareNumbers(x, y)) {
// Do something
if (compareNumbers(y, z)) {
// Do something
if (compareNumbers(z, a)) {
System.out.println("Whatever");
}
}
}
}
public boolean compareNumbers(int a, int b) {
return a < b;
}
}
Which one of those would be better practice? This being a super simple example, imagining you would normally use more complex validations.
And if 'alternate' is better, how many times would the comparison method/function have to be called for it to be better?
I am sorry if this belongs in StackExchange, I wasn't very sure of which one to post it in.
To narrow the scope to StackOverflow lets say this question applies exclusively to Java. Although a general programming view/response would be appreciated.
Extracting code to methods has several advantages:
It makes the code readable
It allows for easily changing the implementation of the method
It allows for unit testing of this specific method
If all your method does is to apply the < operator to the two arguments, I'd say none of the three reasons above apply, and that you're over-complicating things.
Just use the < method, and refactor your code once you need to apply a test with some more "meat" to it.
There are no "industry standards" for this kind of thing. For good reason.
As far as whether a < b is better that compareNumbers(a, b) ... the answer depends on the actual context.
In your example, most people would agree that a < b is better1. But this is an artificial example, and the answer could be different for other (more realistic) examples.
The same goes for all sorts of other questions about the best way to express algorithms, etc in code. It is rare for questions like this to have a single objectively correct answer. It is typically a matter of opinion ... and the context really matters.
But the bottom line is that the only real "industry standard" here is:
Use your professional knowledge, skills and judgement.
... and that means things like:
thinking about each particular problem and finding an appropriate (justifiable) solution,
considering coding effort, readability2, reliability, maintainability for your solution,
considering the economics of the situation; i.e. there is a trade-off between time spent "polishing" your code and time spent doing other things like implementing functionality, testing, writing documentation, meeting deadlines.
1 - If I have to scroll down a couple of pages to check what compareNumbers is doing, this is an impediment ... compared with an inline comparison using <. Now if there was some deeper semantic behind the comparison, then method abstraction could be a good thing, especially if there were comments in the method that explained the semantics. But in this example, compareNumbers(a, b) is less semantically meaningful than a < b.
2 - Another answer states (without supporting evidence) that abstracting code to methods improves readability. This is a gross over-simplification, and often it is demonstrably false. It is important technique ... but not always the right one.
From my personal experience I would use the original compare if I know the conditions are always going to stay the same, however I would use the alternate if there were even the slightest chance of needing to change the conditions. That way I wouldn't have to go back and replace every single condition individually.
To build upon breaking out the methods, I know your example is just that, a quick example, but rather than focus on the evaluation I would focus on the task and organize the code like this:
public void someMethodThatCares(int x, int y, int z, int a)
{
taskXY(x, y);
}
public void taskXY(int x, int y)
{
if (x < y)
{
taskYZ(y, z);
}
}
public void taskYZ(int y, int z)
{
if (y < z)
{
taskZA(z, a);
}
}
public void taskZA(int z, int a)
{
if (z < a)
{
}
}
Now you can build your dependencies as you need them, test each piece of functionality independently, maintain the logic in a clean fashion, and reuse it as needed.
Actually, I focus on the complexity of the code and the importance of that logic in my project. therefore, I might use all alternatives in the same class or even in the same method.
I would suggest reading Design Patterns by the Gang of Four for more information on how to decide. For every problem the approach would be different. For example if you needed to write multiple programs that individually checked each variable, the first program doing a less than check, the second doing a greater than check, the third doing a equals check it may make sense to use the Strategy Design Pattern for each of these cases to prevent the need to create multiple programs and using a Factory creator to decide which Strategy to use. The factory pattern could decide which one to use at run time based on user input or some other method.

Simple, general-interest, code-analyzers based, Java questions [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
OK, after reviewing some code with PMD and FindBugs code analyzers, i was able to do great changes on the reviewed code. However, there are some things i don't know how to fix. I'll iterate them bellow, and (for better reference) i will give each question a number. Feel free to answer to any/all of them. Thanks for your patience.
1. Even tough i have removed some of the rules, the associated warnings are still there, after re-evaluate the code. Any idea why?
2. Please look at the declarations :
private Combo comboAdress;
private ProgressBar pBar;
and the references to objects by getters and setters :
private final Combo getComboAdress() {
return this.comboAdress;
}
private final void setComboAdress(final Combo comboAdress) {
this.comboAdress = comboAdress;
}
private final ProgressBar getpBar() {
return this.pBar;
}
private final void setpBar(final ProgressBar pBar) {
this.pBar = pBar;
}
Now, i wonder why the first declaration don't give me any warning on PMD, while the second gives me the following warning :
Found non-transient, non-static member. Please mark as transient or provide accessors.
More details on that warning here.
3. Here is another warning, also given by PMD :
A method should have only one exit point, and that should be the last statement in the method
More details on that warning here.
Now, i agree with that, but what if i write something like this :
public void actionPerformedOnModifyComboLocations() {
if (getMainTree().isFocusControl()) {
return;
}
....//do stuffs, based on the initial test
}
I tend to agree with the rule, but if performance of the code suggest multiple exit points, what should i do?
4. PMD gives me this :
Found 'DD'-anomaly for variable 'start_page' (lines '319'-'322').
when i declare something like :
String start_page = null;
I get rid of this info (level of warning is info) if i remove the assignment to null, but..i got an error from IDE, saying that the variable could be uninitialized, at some point later in the code. So, i am kind of stuck with that. Supressing the warning is the best you can do?
5. PMD Warning :
Assigning an Object to null is a code smell. Consider refactoring.
This is the case of a singletone use of GUI components or the case of a method who returns complex objects. Assigning the result to null in the catch() section it's justified by the need to avoid the return of an incomplete/inconsistent object. Yes, NullObject should be used, but there are cases where i don't want to do that. Should i supress that warning then?
6. FindBugs warning #1:
Write to static field MyClass.instance from instance method MyClass.handleEvent(Event)
in the method
#Override
public void handleEvent(Event e) {
switch (e.type) {
case SWT.Dispose: {
if (e.widget == getComposite()) {
MyClass.instance = null;
}
break;
}
}
}
of the static variable
private static MyClass instance = null;
The variable allows me to test whether the form is already created and visible or not, and i need to force the re-creation of the form, in some cases. I see no other alternative here. Any insights? (MyClass implements Listener, hence the overrided handleEvent() method).
7. FindBugs warning #2:
Class MyClass2 has a circular dependency with other classes
This warning is displayed based on simple imports of other classes. Do i need to refactor those imports to make this warning go away? Or the problem relies in MyClass2?
OK, enough said for now..expect an update, based on more findings and/or your answers. Thanks.
Here are my answers to some of your questions:
Question number 2:
I think you're not capitalizing the properties properly. The methods should be called getPBar and setPBar.
String pBar;
void setPBar(String str) {...}
String getPBar() { return pBar};
The JavaBeans specification states that:
For readable properties there will be a getter method to read the property value. For writable properties there will be a setter method to allow the property value to be updated. [...] Constructs a PropertyDescriptor for a property that follows the standard Java convention by having getFoo and setFoo accessor methods. Thus if the argument name is "fred", it will assume that the reader method is "getFred" and the writer method is "setFred". Note that the property name should start with a lower case character, which will be capitalized in the method names.
Question number 3:
I agree with the suggestion of the software you're using. For readability, only one exit point is better. For efficiency, using 'return;' might be better. My guess is that the compiler is smart enough to always pick the efficient alternative and I'll bet that the bytecode would be the same in both cases.
FURTHER EMPIRICAL INFORMATION
I did some tests and found out that the java compiler I'm using (javac 1.5.0_19 on Mac OS X 10.4) is not applying the optimization I expected.
I used the following class to test:
public abstract class Test{
public int singleReturn(){
int ret = 0;
if (cond1())
ret = 1;
else if (cond2())
ret = 2;
else if (cond3())
ret = 3;
return ret;
}
public int multReturn(){
if (cond1()) return 1;
else if (cond2()) return 2;
else if (cond3()) return 3;
else return 0;
}
protected abstract boolean cond1();
protected abstract boolean cond2();
protected abstract boolean cond3();
}
Then, I analyzed the bytecode and found that for multReturn() there are several 'ireturn' statements, while there is only one for singleReturn(). Moreover, the bytecode of singleReturn() also includes several goto to the return statement.
I tested both methods with very simple implementations of cond1, cond2 and cond3. I made sure that the three conditions where equally provable. I found out a consistent difference in time of 3% to 6%, in favor of multReturn(). In this case, since the operations are very simple, the impact of the multiple return is quite noticeable.
Then I tested both methods using a more complicated implementation of cond1, cond2 and cond3, in order to make the impact of the different return less evident. I was shocked by the result! Now multReturn() is consistently slower than singleReturn() (between 2% and 3%). I don't know what is causing this difference because the rest of the code should be equal.
I think these unexpected results are caused by the JIT compiler of the JVM.
Anyway, I stand by my initial intuition: the compiler (or the JIT) can optimize these kind of things and this frees the developer to focus on writing code that is easily readable and maintainable.
Question number 6:
You could call a class method from your instance method and leave that static method alter the class variable.
Then, your code look similar to the following:
public static void clearInstance() {
instance = null;
}
#Override
public void handleEvent(Event e) {
switch (e.type) {
case SWT.Dispose: {
if (e.widget == getComposite()) {
MyClass.clearInstance();
}
break;
}
}
}
This would cause the warning you described in 5, but there has to be some compromise, and in this case it's just a smell, not an error.
Question number 7:
This is simply a smell of a possible problem. It's not necessarily bad or wrong, and you cannot be sure just by using this tool.
If you've got a real problem, like dependencies between constructors, testing should show it.
A different, but related, problem are circular dependencies between jars: while classes with circular dependencies can be compiled, circular dependencies between jars cannot be handled in the JVM because of the way class loaders work.
I have no idea. It seems likely that whatever you did do, it was not what you were attempting to do!
Perhaps the declarations appear in a Serializable class but that the type (e.g. ComboProgress are not themselves serializable). If this is UI code, then that seems very likely. I would merely comment the class to indicate that it should not be serialized.
This is a valid warning. You can refactor your code thus:
public void actionPerformedOnModifyComboLocations() {
if (!getMainTree().isFocusControl()) {
....//do stuffs, based on the initial test
}
}
This is why I can't stand static analysis tools. A null assignment obviously leaves you open to NullPointerExceptions later. However, there are plenty of places where this is simply unavoidable (e.g. using try catch finally to do resource cleanup using a Closeable)
This also seems like a valid warning and your use of static access would probably be considered a code smell by most developers. Consider refactoring via using dependency-injection to inject the resource-tracker into the classes where you use the static at the moment.
If your class has unused imports then these should be removed. This might make the warnings disappear. On the other hand, if the imports are required, you may have a genuine circular dependency, which is something like this:
class A {
private B b;
}
class B {
private A a;
}
This is usually a confusing state of affairs and leaves you open to an initialization problem. For example, you may accidentally add some code in the initialization of A that requires its B instance to be initialized. If you add similar code into B, then the circular dependency would mean that your code was actually broken (i.e. you couldn't construct either an A or a B.
Again an illustration of why I really don't like static analysis tools - they usually just provide you with a bunch of false positives. The circular-dependent code may work perfectly well and be extremely well-documented.
For point 3, probably the majority of developers these days would say the single-return rule is simply flat wrong, and on average leads to worse code. Others see that it a written-down rule, with historical credentials, some code that breaks it is hard to read, and so not following it is simply wrong.
You seem to agree with the first camp, but lack the confidence to tell the tool to turn off that rule.
The thing to remember is it is an easy rule to code in any checking tool, and some people do want it. So it is pretty much always implemented by them.
Whereas few (if any) enforce the more subjective 'guard; body; return calculation;' pattern that generally produces the easiest-to-read and simplest code.
So if you are looking at producing good code, rather than simply avoiding the worst code, that is one rule you probably do want to turn off.

Categories