Currently, I use a very conservative way to stop malfunctioing code. It is annoying at the time of a change when I have to change the checker parts as well.
if(ds==null||s==null||maxDs==null)
{
System.out.println("NULL in getDirs(ds[],s,maxDs)");
System.exit(9);
}
So is there some prebuild-ready Null checker for pars in the API?
Does Java build some ready table for Parameters? Perhaps similar to Stdin argv[].
If so, where can I find all automatically build tables like argv[]?
Wanna-check-for-parameters
for(Object p:pars)
{
if(p.isNull())
{
System.out.println("Lollipop arg your pars are in Lava!");
System.exit(9);
}
}
I'm not aware of anything built in, but it should be possible to write your own annotation processet to inject some suitable code. It seems possible that only some methods need a null check, so having the control that annotations would give could be useful.
#ParamNotNull
public void myMethod(X anX, Y aY) { ...
public void myTolerantMethod(X couldbeNull) { ...
Related
To avoid a null pointer exception in my equals(), I have to consider the possibility of one or more nulls.
Is there a scalable way for considering nulls? The following code will become ugly quite fast if I add more type parameters.
public boolean equals(Pair<T, U> p) {
boolean firstIsEqual, secondIsEqual;
if (p.getFirst()==null) {
firstIsEqual = first == null;
}
else {
firstIsEqual = (first!=null) && (first.equals(p.getFirst()));
}
// copy-paste...
if (p.getSecond()==null) {
secondIsEqual = second == null;
}
else {
secondIsEqual = (second!=null) && (second.equals(p.getSecond()));
}
return (firstIsEqual && secondIsEqual);
}
The only solution that scale are:
to use a library like Lombok that provide means to generate such methods during the compile phase
to use the built-in code generation features of your IDE
Seriously: nobody in the real world writes equals/hashCode methods manually. You use a tool and tell that which fields should be used in the computation. If a field is added, you have to remember to re-generate the methods.
Or you use a jvm language that supports data classes such as Kotlin or Scala.
I've been given a class with some 200 fields in which their values are read using reflection. It looks basically like this
for (Field f : this.getClass().getFields())
{
try
{
Object o = f.get(this);
if (f.getType() == String.class)
{
//do things with the string
}
}
catch (Exception ex)
{
logger.error("Cannot get value for field. {}", ex.getMessage());
}
}
This works very well for such an unwieldy amount of fields as I suppose is the point of reflection. I've been asked to refactor it because it's slow (is it?).
So far the only method I can come up with his an ungodly amount of hard coding, is there another quick method?
First you should verify with a profiler that it indeed is slow. Reflection is slower than accessing variables normally, but that doesn't necessarily mean that it's the source of slowness.
Provided that you're using setters to modify those values, you can refactor the class to update a Map<String,Object> whenever a setter is called. This provides faster access to the fields than reflection, but may not be possible depending on your use case.
Most of the time is spent in obtaining the Field objects (and possibly filtering them) The actual lookup can be pretty fast. I use ClassValue to cache this information and speed it up.
public enum StringFields {
INSTANCE;
final ClassValue<List<Field>> fieldsCache = new ClassValue<List<Field>>() {
#Override
protected List<Field> computeValue(Class<?> type) {
return Collections.unmodifiableList(
Stream.of(type.getFields())
.filter(f -> f.getType() == String.class)
.peek(f -> f.setAccessible(true)) // turn off security check
.collect(Collectors.toList()));
}
};
public static List<Field> getAllStringFields(Class<?> type) {
return INSTANCE.fieldsCache.get(type);
}
}
So far the only method I can come up with his an ungodly amount of hard coding, is there another quick method?
You can use reflection to get the getters of those fields and generate code which reads out those getters.
The code generation can then be part of a build step.
In my code, I am making a lot of checks for null so that I don't get a NullPointerException usually i am just doing like this:
if(variable != null){
//do something with the variable
}
Is the following better in any way or is it just a matter or personal belief?
if( !variable.equals(null) ){
//do something with the variable
}
Is there a more efficient way to make this check?
Btw I do have done my research already but I cant seem to find concrete evidence to prove either point.
P.S This is a NOT duplicate of Avoiding != null statements, on that the best answer is that you should either use Assert, which cannot be used to run code rather than just display a message, or actually throw the exception which I dont want either. This post is addressing a different issue of the same subject.
if(!variable.equals(null) ){
//do something with the variable
}
If variable is null NPE occurs. First method is far better.
EDIT:
Using Optional:
Consider that you have Person object and want to getSalary(). Unfortunately age can be null - in that case you want default value. You can do Integer salary = Optional.ofNullable(person.getSalary()).orElse(2000). It will return salarty from person or 2000 in case salary is null.
Or you can use java.util.Optional from Java 8.
Very nice examples are on JavaCodeGeeks.
Optional is usually used in java.util.stream lambdas for "functional-style operations".
As others already said, the variant
if(!variable.equals(null))
can NPE itself when variable is null. Furthermore, you have to be sure that the equals method also is null-safe for all object types you use. Thus, if you absolutely need to check, use ==.
As for better solutions (we're going opinion-based here): I think that this ecessive null-checking is a sign of brittle software and suboptimal interface definition. What I currently try to do more and more is use the javax.validation annotation #NotNull to harden my interfaces and get rid off all these runtime checks:
private #NotNull String getName() {...} // guaranteed not to return null
...
if(getName() == null) { // superfluos, your IDE gives a shout if configurd correctly
...
}
... give it a shot :)
Edit (as an answer to the comment, as I need code-formatting):
Here's a complete cut&paste-example from my current eclipse setup:
package stuff;
import javax.validation.constraints.NotNull;
public class Try3 {
public #NotNull String getName() { return ""; }
public void test() {
if(getName() == null)
System.out.println("Cannot happen due to contract");
}
}
Ensure, that the imported type is indeed javax.validation.constraints.NotNull (as other frameworks also have a NotNull annotation, which may be defined in a different way). For eclipse, you also have to check "Enable annotation-based null analysis" in the project settings under JavaCompiler / Errors/Warnings and customize the annotations to use, as eclipse defaults to some home-brewed annotations. The customization can be accessed via the link "Configure" after the checkbox for using default annotations in the same settings page. Hope that helps!
There are two approaches:
public void calculate(Class variable) {
Assert.notNull(variable, "variable was null");
//calculations
}
//and
if (variable == null) {
//bad
} else {
calculate(variable);
}
The second one is the most common one. If your variable is a String consider using Guava.StringUtils with it's fantastic isBlank method which checks if the String is null or ""
Summarizing:
if (variable == null) {
//bad
} else {
//good
}
The above is standard approach. The better approach will be:
private boolean isNull(Class variable) {
return variable == null;
}
if (isNull(variable)) {
} else {
}
I used to do call the below method all the time which checks for nullpointer exception
public static boolean isAvailable(Object data) {
return ((data!=null) && (data.toString().trim().length() > 0));
}
I'm generating Java source code with JCodeModel and want to get an "if-elseif" block like this:
if (foo){
} else if (bar) {
}
As far as I understand the according code would be something like this (where m is a JMethod):
JConditional cond = m.body()._if(JExpr.direct("foo"));
cond._elseif(JExpr.direct("bar"));
Seems to be straight forward, but the result is this:
if (foo) {
} else {
if (bar) {
}
}
You see the syntactic difference, it's not actually an "elseif". Semantically it's the same, I know, but I need it to be generated as shown before (it's part of educational software). Any way to do this?
Unfortunately you can not do this using JConditional because of its implementation. Have a look at the source of the method _elseif:
public JConditional _elseif(JExpression boolExp) {
return _else()._if(boolExp);
}
As you can see, this method just invoke _else() and then _if internally.
Actually _else() is JBlock which contains braces ({ ... }) by default. This property of JBlock can not be switched off manually because it doesn't contain such setter. braces could be switched off only through special constructor of JBlock:
public JBlock(boolean bracesRequired, boolean indentRequired) {
this.bracesRequired = bracesRequired;
this.indentRequired = indentRequired;
}
but you are not able to set you own object to _else field of JConditional object outwardly.
The only way is copy JConditional class implementation and generate your own, which will allow you such code manipulation.
UPD: Of course you can always use Reflection as workaround for manually switching flag bracesRequired of _else object to false.
We have App A as main app. Now we build from it App B which uses a subset of App A's functionality.
App A stays like it is whereas app B only uses a subset of A
So I want to refactor the function without or with as little dublication as possible and with maximum readability.
So the function looks like this (it is actually longer, this is an excerpt):
class SomeClass {
Data prepareData() {
if (this.bothId==1 || this.appAid=2 /*or only relevant for appA*/) {
if(this.data==null) { /*appA*/
appAdoSmth(); /*appA*/
}
boolean merge=false; /*appA*/
if (this.data==null) { /*appA*/
merge=appAanalyze(data); /*appA*/
}
bothPrepare(merge);
} else if (bothIsRelevant()) {
if(appArelevant()) { /*appA*/
data=appAprepare(); /*appA*/
} else {
data=prepareBoth();
}
bothUpdateSomeValue();
}
}
How would you do it?
Other Answers address the general question of how to refactor code. They offer good advice, but I don't think it is what you are asking.
I think you are asking about possible refactorings of the code in your question.
It is hard to give an answer that is generally applicable, or even specifically applicable. (The sample code isn't your real code, and it is a little difficult to understand what it actually "means").
AndreasD gives one approach: break the big complicated nested if into separate methods.
Another approach is to use the Stragegy design pattern. Separate the code that is specific to each app into strategy classes. For example:
interface Strategy {
Data prepareData();
}
class GeneralStrategy implements Strategy {
Data prepareData() {
// do general preparation
}
}
class App1Strategy extends GeneralStrategy {
Data prepareData() {
// do app1-specific preparation
super.prepareData();
// do more app1-specific preparation
}
}
and so on.
I ideal world develop unit test that validates that existing implementation of your function works.
Then start changing code incrementally and run your test after every change.
It is hard to give your formal recommendation without knowing your code structure. But generally try to find duplicate code fragments, write methods that implement this logic with parameters and replace the duplicate fragments to your new method. Etc, etc.
Good luck.
Readbility can be improved by extracting some logic in separate methods. That is a refactoring method.
Data prepareData() {
if (this.bothId==1 || this.appAid=2 ) {
handleCase1(); // <- you'll find better names for the methods
} else if (bothIsRelevant()) {
handleCase2();
}
}
private void handleCase1() {
if(this.data==null) {
appAdoSmth();
}
boolean merge=false;
if (this.data==null) {
merge=appAanalyze(data);
}
bothPrepare(merge);
}
private handleCase2() {
if(appArelevant()) {
data=appAprepare();
} else {
data=prepareBoth();
}
bothUpdateSomeValue();
}
This doesn't reduce the number of if/else, of course, but it keeps the "main" method simple.
If I were you I would run a coverage report on this class. (e.g. http://ecobertura.johoop.de/ or http://www.eclemma.org/) This way Eclipse can show covered lines green and this helps you to identify the cases. With this aid it's much easier to separate green lines and pull them into methods.