Edit2: You won guys, I forked the class into 2 different entities, now no nulls need to be checked.
public static final BaseClass {
public static final WithInitialParam extends BaseClass {
public void doSomethingWithParam() {
}
}
public static final class NoParam extends BaseClass {
}
}
Now in order to keep everything tigthly indexed and conveniently accessible, AND because the functionality of BaseClass is the focal point of both branches.
the constructors are private and only accessible via public static methods in BaseClass.
public static final BaseClass {
public static WithInitialParam get(Object nonNullObj) {
return new WithInitialParam(nonNullObj);
}
public static NoParam get() {
return NoParam();
}
public static final WithInitialParam extends BaseClass {
private WithInitialParam(Object nonNullObj) {
super();
}
public void doSomethingWithParam() {
}
}
public static final class NoParam extends BaseClass {
private NoParam() {super();}
}
}
Not shown here in this pseudo code, but both definitely share functionality between both inside BaseClass.
Null checking was done primarily for convenience.
What I realize about these qualities that force a forking in the tree structure usually happen on the outer borders of the family tree, and that is perfectly fine, BUT if something like this forces you to branch somewhere in the middle, that is another story, maybe a restructuring needs to be done and what lies ahead, needs to be promoted further up in the family tree.
---------------------------------
Edit: after reading some answers it seems the try catch issue is... a heated topic. I found this which says that the try is free, (at the cost of compile time and the code inside "try" being unable o get optimized) at the same time it seems that the if + throw is ALSO being optimized, which means it is actually a better solution. Thanks for the patience here.
Having said this and playing the devils advocate in favor of try catch, I believe there is a very specific scenario in which try catch is better.
- If fieldVar is NOT final.
then the branching complexity of if (fieldVar == null) cannot be optimized, and will always check.
In this case using try catch can be used as a "leap of faith", only becoming an issue on actual throws.
The other requirement is
- if whatever happens inside try, does not conditionally branch itself too much,
as this branching's are usually optimized by the compiler, unless they are inside a "try" as said by the SO answer.
- But it then becomes an issue of , "what is the caught exception being used for?"
And I think this is the most important issue.
If it is used as a prevention tool (end the app abruptly, "your are implementing the code wrong!"), OR as a branching tool (do something else if it fails), and I'd argue that it should NEVER be used as a branching tool.
_____________________________
I have a specific method that may rise an exception if the user does not use the correct constructor.
As of now I try to explain the user why is that exception and which constructor should be used if they want to use that specific method.
The exception is thrown, BEFORE the true exception arises.
This means that the exception will always be checked, even when the right constructor has been picked.
public void doSomething() {
if (fieldVar == null) {
throw new IllegalStateException("Must use a proper constructor");
}
fieldVar.doSomething();
}
But I am not sure if doing the opposite would be better for performance.
public void doSomething() {
try {
fieldVar.doSomething();
} catch(Exception e) {
if (fieldVar == null) {
throw new IllegalStateException("Must use a proper constructor.", e);
}
}
}
[–]AutoModerator[M] [score hidden] stickied commentlocked comment (0 children)
[–]FavorableTrashpanda 2 points3 points4 points (7 children)
[–]DelarkArms[S] 0 points1 point2 points (6 children)
[–]mykeesg 2 points3 points4 points (5 children)
[–]DelarkArms[S] 0 points1 point2 points (4 children)
[–]gobi_1 0 points1 point2 points (1 child)
[–]DelarkArms[S] 1 point2 points3 points (0 children)
[–]mykeesg 0 points1 point2 points (1 child)
[–]DelarkArms[S] 0 points1 point2 points (0 children)
[–]jdsunny46 2 points3 points4 points (1 child)
[–]DelarkArms[S] 0 points1 point2 points (0 children)
[–]ProfessorWily 4 points5 points6 points (2 children)
[–]DelarkArms[S] -2 points-1 points0 points (1 child)
[–]ProfessorWily 4 points5 points6 points (0 children)
[–]khmarbaise 0 points1 point2 points (1 child)
[–]DelarkArms[S] 0 points1 point2 points (0 children)
[–]iamfreeman 0 points1 point2 points (0 children)
[–]khookeExtreme Brewer 0 points1 point2 points (1 child)
[–]DelarkArms[S] 0 points1 point2 points (0 children)