I have very very little experience with Java and I'm facing some issues.
I've got a code that looks like the one below and a goal to kill all mutations of it.
public class MyClass {
protected transient boolean something = false;
public MyClass () {
something = true;
}
boolean isSomething () {
return something;
}
}
My test code looks like this
tester = MyClass();
assertTrue(tester.isSomething());
By running it with pitest, on Eclipse, it would generate the following mutations (all related to the return something statement):
Substituted 1 with 0
Removed assignment to member variable something
Substituted 1 with 0
Substituted 1 with -1
Substituted 1 with -1
Substituted 1 with 2
Substituted 1 with 0
Unfortunately, I just can't kill those 4 and 5 mutations, both that substitutes 1 with -1. Is there a way I could kill them?
There are a few issues here.
Firstly you look to have some experimental/research mutation operators enabled which are generating junk mutations. This will not happen if you stick with the default set.
As at the jvm level booleans are represented as integers of 0/1. Only the following mutations make sense
Substituted 1 with 0
Removed assignment to member variable something
(note that although the mutation makes sense in this case, the removal of member assignments is disabled by default as it can produce equivalent mutants)
You don't provide the full context so it is not clear if the repeated 1/0 substitutions are duplicates or distinct.
To kill these mutants there are two approaches. Firstly remove redundant code.
public class MyClass {
protected transient boolean something = true;
boolean isSomething () {
return something;
}
}
This is functionaly equivalent to the original code, but there is less of it.
Secondly you need tests.
Since you have made something protected I assume that MyClass has subclasses? If it does not then then code could be further reduced down to
public class MyClass {
boolean isSomething () {
return true;
}
}
And there is only one test you can write.
assertThat(new MyClass().isSomething()).isTrue();
If there are subclasses then you need tests that check that setup something to be true, and then assert that isSomething returns true, and another that sets it up to be false and asserts the method returns false.
Related
I do have the following statement:
isEnabled = false;
if(foo(arg) && isEnabled) {
....
}
public boolean foo(arg) {
some really long running code
}
Does it make sense to swap the statements inside the if?
if(isEnabled && foo(arg)) { ... }
Or does the compiler the optimization for me?
Note that the two expressions don't have the same behavior if foo() also has side effects.
If it is manipulating the state of the program, it makes a lot of difference if you always invoke it, or if you invoke it only as a dependency of the value of isEnabled.
For example, consider:
boolean foo(Object arg) {
someLocalVariable = arg;
//do some calculation and return an answer
}
It matters if you always invoke foo(), or if you invoke it only in the case where isEnabled is turned on, resulting in the following two expressions to be completely different from each other:
if (isEnabled && foo(arg)) { ...} //local variable changes only if isEnabled==true
if (foo(arg) && isEnabled) { ...} //local variable always changes
The compiler will not do any optimization in this case.
if(isEnabled && foo(arg)) { ... }
Is always the better approach.
Because i guess you know that when isEnabled is false it will not evaluate foo(arg). And compiler will maintain your sequence of instruction.
Does it make sense to swap the statements inside the if?
Yes. && will only evalute the sub-expressions until one is false. Then the complete exprission will be false, no matter what the other expressions evaluate to.
Since the compiler would have to keep the logic as it is (which includes the order of statements) it won't optimize that.
Suppose foo() has a side effect which some other part of the code relies on, changing the order might break that. Of course this isn't good style in most cases but the compiler can't rely on or enforce style so it has to trust the developer here.
Example:
int x = 0;
boolean foo(int arg) {
x = arg;
return x > 0;
}
void someMethod(int arg) {
boolean isEnabled = false;
if(foo(arg) && isEnabled) {
//whatever
}
//here you use x, I'll simply print it
System.out.println("x=" + x);
}
void someOtherMethod(int arg) {
boolean isEnabled = false;
if(isEnabled && foo(arg)) {
//whatever
}
//here you use x, I'll simply print it
System.out.println("x=" + x);
}
Now calling the methods:
someOtherMethod(7); //foo(7) will not be called so x will still be 0
someMethod(5);
you'll get the output
x=0
x=5
First of all, the Java compiler (which turns java source into bytecode) is pretty dumb. Out of the many optimization techniques known to compiler constructors, just a handful (like constant folding) are implemented by javac.
Whereas the Java just-in-time compiler does many many more things; but even the JIT will not change the order of arguments for you (as that can change the semantics of the underlying program).
Finally, when thinking about this code, performance should not be the motivation behind you changing it. Instead, you should worry about the semantics too. Do you want that foo() is executed (for side effects); or maybe do you not want that foo() runs all the time?
Of course, "foo()" could be doing many many things; and not executing it might gain some performance. But most likely: it will not matter (from a performance perspective).
In other words: stay away from micro-optimisations, see here for backing reasons to that recommendation.
Why do I get no dead code warning for the initialisation of someVal here?
public class DeadCode {
private int someVal = 0;
public DeadCode(int someVal) {
this.someVal = someVal;
}
public int getSomeVal() {
return someVal;
}
public void setSomeVal(int someVal) {
this.someVal = someVal;
}
}
The Java compiler is supposed to pick up on dead code and issue a warning; but this is dead twice over, and passes by without a hitch.
It's dead twice over because
Java automatically initialises instance fields to 0 or equivalent;
the value of someVal can't be read without being written to.
I realise that the compiler can elide the assignment if it wants to, but that's true (by definition) of all dead code.
If there is a distinction to be made between dead code and code that has no effect, then I would expect
The assignment to variable someVal has no effect.
which is what I would get if I wrote
someVal = someVal;
in my code. But I don't get that either.
In any case, Wikipedia sees dead code elimination as removal of code that has no effect on program results; and this is certainly a case of that.
I think the real answer is that many people would find a warning for that code to be pretty annoying.
As a technicality, though, the initializer does not constitute dead code because its effect can, in principle, be observed in an improperly synchronized multithreaded program.
Integer field is a simplistic use case. What if you had something like this, notice the parameterless constructor:
public class DeadCode {
private List<Integer> someVal = new ArrayList<>();
public DeadCode() {
}
public DeadCode(Iterable<Integer> someVal) {
this.someVal.addAll(someVal);
}
public Iterable<Integer> getSomeVal() {
return someVal;
}
public void addSomeVal(int someVal) {
this.someVal.add(someVal);
}
}
You have to create a list, yes you could do it in the constructor Now the compiler needs to be a lot more intelligent to be able to determine in which cases it wasteful to initialize field. I guess they opted for consistent and straightforward behavior.
I was wondering if it was possible to do a ternary operation but without returning anything.
If it's not possible in Java is it possible in other languages, if so which ones apply?
name.isChecked() ? name.setChecked(true):name.setChecked(false);
No, you can't. But what's the point of this over an if-else statement? Are you really trying to save 7 characters?
if (name.isChecked()) {
name.setChecked(true);
} else {
name.setChecked(false);
}
or if you prefer bad style:
if (name.isChecked()) name.setChecked(true); else name.setChecked(false);
Never mind the fact that you can just do (in this case):
name.setChecked(name.isChecked());
The point of the ternary or "conditional" operator is to introduce conditionals into an expression. In other words, this:
int max = a > b ? a : b;
is meant to be shorthand for this:
int max;
if ( a > b ) {
max = a;
} else {
max = b;
}
If there is no value being produced, the conditional operator is not a shortcut.
I was wondering if it was possible to do a ternary operation but without returning anything.
No it is not possible:
The 2nd and 3rd operands are required to be non-void expressions; i.e. they must produce some actual value.
"It is a compile-time error for either the second or the third operand expression to be an invocation of a void method." - JLS 15.25.
A ternary expression is an expression, and cannot be used as a statement.
"Certain kinds of expressions may be used as statements by following them with semicolons." ... and the ternary expression is not one of those kinds - JLS 14.8.
If you really, really want to use a ternary expression but not use the value of the expression, then the simplest thing is to assign the value to a dummy variable, and add an annotation to suppress the warning about the variable not being used.
But a better idea is to use a plain if statement.
If it's not possible in Java is it possible in other languages, if so which ones apply?
I'm a bit rusty, but I believe that C, C++ and Perl all allow arbitrary expressions to be used in places where their values are not used.
Sometimes, you can use ternary operation on method arguments to solve your request.
name.setChecked(name.isChecked() ? true : false);
By the way, the best solution for your problem is
name.setChecked(name.isChecked());
I assume the use case in the question is just a poor example because it's equivalent to the following statement:
name.setChecked(name.isChecked());
... which doesn't make sense either. But the intent is clear and there are indeed many relevant use cases.
The only viable and general solution is adding a helper method like this:
static void ternaryVoid(boolean condition, Runnable ifTrue, Runnable ifFalse) {
(condition ? ifTrue : ifFalse).run();
}
and using it like this:
ternaryVoid(name.isChecked(), () -> name.setChecked(true), () -> name.setChecked(false));
But it loses the elegance of ternary operator and worth the 'effort' only if used by multiple parts of the code and only if nanoseconds don't matter.
But what's the point of this over an if-else statement? Are you really trying to save 7 characters?
I'm surprised that such statements appear in a form of rhetorical questions. Yes, saving 4 lines and making the code more elegant is important, especially in the context of functional programming.
Moreover, it's at least arguable whether void methods return a complete Void. Essentially, they return a notification of a completed task. This is why logically, ternary expression makes sense equally regardless of whether it returns something or nothing:
condition ? doThis() : doThat();
Here is a real world example of a class which may process millions of incremental updates per second:
public class DataHandler {
private final TreeMap<Integer, Long> tree = new TreeMap<>();
public void onUpdate(int price, long amount) {
if (amount == 0) {
tree.remove(price);
} else {
tree.put(price, amount);
}
}
}
If allowed, the onUpdate() method would be a nice ternary expression like this:
public void onUpdate(int price, long amount) {
(amount == 0) ? tree.remove(price) : tree.put(price, amount); // compilation error
}
Fortunately, in some cases like this, both target methods return values, and these values are of the same type, which is Long in this case. This allows either to make the onUpdate method to return the previous amount at price (which is even useful)
public Long onUpdate(int price, long amount) {
return (amount == 0) ? tree.remove(price) : tree.put(price, amount);
}
... or alternatively (e.g. in case the method is determined by an interface), to use a dummy variable and suppress its uselessness warning:
public void onUpdate(int price, long amount) {
#SuppressWarnings("unused")
Long dummy = (amount == 0) ? tree.remove(price) : tree.put(price, amount);
}
Otherwise, these solutions are not applicable, and as answered by others, doesn't exist. For instance, one may try the following:
Consumer<Void> dummy = (x) -> {};
dummy.accept(/*...*/);
but interestingly, the second line compiles with neither anything nor nothing as an argument.
It seems the best general solution is the above helper method ternaryVoid().
You have to return some value and it will not work if you want it to act like a void method which performs some action without a returning a value.
Hope this helps...
In java following code isn't possible:
(your-condition) ? (true-statements) : (false-statements)
for sample you can't compile following snipet code :
(1==1) ? System.out.println("") : System.out.println("");
you achieve following compilation error:
The left-hand side of an assignment must be a variable
As we know, Class#isAssignable does not consider, that a value can be auto boxed/unboxed. E.g. the lower of the four following cases return false:
// obvious
System.out.println(boolean.class.isAssignableFrom(boolean.class)); // true
System.out.println(Boolean.class.isAssignableFrom(Boolean.class)); // true
// boxing/unboxing
System.out.println(boolean.class.isAssignableFrom(Boolean.class)); // false
System.out.println(Boolean.class.isAssignableFrom(boolean.class)); // false
Is there a pre-existing variant of this method which would consider this case? (i.e. returning true in all four given cases above.) If not, what would be the best way of implementing this for all primitive/wrapped combinations?
This method is about subtyping, not whether one value can be assigned to a variable, which is much more complex, see http://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.2
I have a WRAPPER_MAP field like this.
WRAPPER_MAP.put(boolean.class, Boolean.class);
// add others
then I look this up.
public static Class wrap(Class clazz) {
Class clazz2 = WRAPPER_MAP.get(clazz);
return clazz2 == null ? clazz : clazz2;
}
Then the test is
wrap(clazz1).isAssignableFrom(wrap(clazz2));
This is maybe so silly.
I have a boolean variable inside the main method. By calling another method of this class or another class I want my boolean value to be modified in the main method. I do this but the change happens only in the called method(locally), not the caller(main). I think this is because of the pass-by-value feature of java.
I even tried Boolean type, but the same problem there!
Actually I'll use this to manage the ordering of concurrent threads. The main processor will check for the boolean value of every thread to see if it is ok to continue and tick the clock. After ticking the clock the main will make the vars false and will wait until the vars are again true. the sub-threads will start their task if the boolean value of them each is false. After the task is done they will make the vars to true so the main processor is able to tick again.
So I want something without a return. I mean as the value is changed inside the method the main could see it.
boolean var = true;
var = methodWhichReturnsTheNewValueOfTheVariable();
and inside the called method:
return newBooleanValue;
or
SomeObjectWithBooleanVariableInside var = new SomeObjectWithBooleanVariableInside(true);
methodWhichModifiesTheObject(var);
and inside the called method:
var.setBooleanValue(newBooleanValue);
A Boolean is such an object: it contains a boolean value. But it's intentionally designed as immutable: its wrapped boolean value can't be changed. So you need to create your own, functional object.
The usual way to do this is the following:
public static void main(String[] args) {
boolean myVar = true;
...
...
myVar = myFunction();
}
public static boolean myFunction() {
// the method should do it's calculation and return the value:
return false;
}
Yes - you cannot modify passed-by-value parameter inside a method in Java (for example in C# you would write method(ref param)).
Why can't you return this value using the method:
public boolean method(params...) {...}
Or you can pass in param the reference to caller:
public void method(params..., CallerClass caller) {
//do something
caller.setValue(Boolean.FALSE);
}
Or you can make this variable accessible in caller and calling method scopes - static variable, etc.
Primitive types are passed by value, so you can't change variables coming as parameter in a method.
This makes also easier to understand how a program works, since this kind of behavior is made more evident in an invocation like this:
boolean prime = false;
prime = isPrime(number);
you can see that found variable is reassigned; while you can assume that number will remain unchanged. This helps in code readability.
There is a dirty trick that sometime can be used. Since arrays are objects, you can use an array to wrap a primitive type:
boolean[] prime = { false };
isPrime(number, result);
public void isPrime(int number, boolean[] result) {
result[0] = true;
}
The object reference is passed by value too, but here we change the content of the array, not the array reference.
This works. But, I don't recommend to design your code like this.
Sometimes, knowing this trick can be useful in unit tests though.
when you think that you changed the value of the primitive boolean it only changed the value in the scope of that method. same with Boolean as it is immutable. changing its value actually assigned a new value to it inside the scope of that method.
you should return the new value from that method and then assign it or you could also use a global boolean that is known to all and to change that one.
(and by the way, if you're dealing with concurrency check out AtomicBoolean)