Sometimes conditions can become quite complex, so for readability I usually split them up and give each component a meaningful name. This defeats short-circuit evaluation ho
The BooleanExpression type doesn't seem to be useful enough to be a class on its own outside your main class and it adds some intellectual weight to your application too. I would simply just write private methods that are named appropriately to run the checks you want. It's much simpler.
Your first solution is good for this kind of complexity. If the conditions were more complex, I would write private methods for each check you need to run. Something like:
public class DemoStackOverflow {
public static void main(String[] args) {
if ( areValid(args) ) {
System.out.println("Arguments OK");
}
}
/**
* Validation of parameters.
*
* @param args an array with the parameters to validate.
* @return true if the arguments are not null, the quantity of arguments match
* the expected quantity and the first and second are not equal;
* false, otherwise.
*/
private static boolean areValid(String[] args) {
return notNull(args) && lengthOK(args) && areDifferent(args);
}
private static boolean notNull(String[] args) {
return args != null;
}
private static boolean lengthOK(String[] args) {
return args.length == EXPECTED_ARGS;
}
private static boolean areDifferent(String[] args) {
return !args[0].equals(args[1]);
}
/** Quantity of expected arguments */
private static final int EXPECTED_ARGS = 2;
}
You must do the variable assignment INSIDE the if's.
if (a && b && c) ...
translates to
calculatedA = a;
if (calculatedA) {
calculatedB = b;
if (calculatedB) {
calculatedC = c;
if (calculatedC) ....
}
}
It is often beneficial to do this anyway since it names the concepts you are testing for, as you demonstrate clearly in your example code. This increases readability.
You can use early returns (from a method) to achieve the same effect:
[Some fixes applied]
public static boolean areArgsOk(String[] args) {
if(args == null)
return false;
if(args.length != 2)
return false;
if(args[0].equals(args[1]))
return false;
return true;
}
public static void main2(String[] args) {
boolean b = areArgsOk(args);
if(b)
System.out.println("Args are ok");
}
Split it out into a separate function (to improve readability in main()) and add a comment (so people understand what you are trying to accomplish)
public static void main(String[] args) {
if (argumentsAreValid(args)) {
System.out.println("Args are ok");
}
}
public static boolean argumentsAreValid(String[] args) {
// Must have 2 arguments (and the second can't be the same as the first)
return args == null || args.length == 2 || !args[0].equals(args[1]);
}
ETA: I also like Itay's idea of using early returns in the ArgumentsAreValid function to improve the readability.
There's really nothing wrong with the first piece of code; you're overthinking things, IMO.
Here's another way that, while verbose, is easy to understand.
static void usage() {
System.err.println("Usage: blah blah blah blah");
System.exit(-1);
}
// ...
if (args == null || args.length < 2)
usage();
if (args[0].equals(args[1]))
usage()