What does the "assert" keyword do? [duplicate] - java

This question already has answers here:
What does the Java assert keyword do, and when should it be used?
(20 answers)
Closed 5 years ago.
What does assert do?
For example in the function:
private static int charAt(String s, int d) {
assert d >= 0 && d <= s.length();
if (d == s.length()) return -1;
return s.charAt(d);
}

If you launch your program with -enableassertions (or -ea for short) then this statement
assert cond;
is equivalent to
if (!cond)
throw new AssertionError();
If you launch your program without this option, the assert statement will have no effect.
For example, assert d >= 0 && d <= s.length();, as posted in your question, is equivalent to
if (!(d >= 0 && d <= s.length()))
throw new AssertionError();
(If you launched with -enableassertions that is.)
Formally, the Java Language Specification: 14.10. The assert Statement says the following:
14.10. The assert Statement
An assertion is an assert statement containing a boolean expression. An assertion is either enabled or disabled. If the assertion is enabled, execution of the assertion causes evaluation of the boolean expression and an error is reported if the expression evaluates to false. If the assertion is disabled, execution of the assertion has no effect whatsoever.
Where "enabled or disabled" is controlled with the -ea switch and "An error is reported" means that an AssertionError is thrown.
And finally, a lesser known feature of assert:
You can append : "Error message" like this:
assert d != null : "d is null";
to specify what the error message of the thrown AssertionError should be.
This post has been rewritten as an article here.

If the condition isn't satisfied, an AssertionError will be thrown.
Assertions have to be enabled, though; otherwise the assert expression does nothing. See:
http://java.sun.com/j2se/1.5.0/docs/guide/language/assert.html#enable-disable

assert is a debugging tool that will cause the program to throw an AssertionFailed exception if the condition is not true. In this case, the program will throw an exception if either of the two conditions following it evaluate to false. Generally speaking, assert should not be used in production code

Although I have read a lot documentation about this one, I'm still confusing on how, when, and where to use it.
Make it very simple to understand:
When you have a similar situation like this:
String strA = null;
String strB = null;
if (2 > 1){
strA = "Hello World";
}
strB = strA.toLowerCase();
You might receive warning (displaying yellow line on strB = strA.toLowerCase(); ) that strA might produce a NULL value to strB. Although you know that strB is absolutely won't be null in the end, just in case, you use assert to
1. Disable the warning.
2. Throw Exception error IF worst thing happens (when you run your application).
Sometime, when you compile your code, you don't get your result and it's a bug. But the application won't crash, and you spend a very hard time to find where is causing this bug.
So, if you put assert, like this:
assert strA != null; //Adding here
strB = strA .toLowerCase();
you tell the compiler that strA is absolutely not a null value, it can 'peacefully' turn off the warning. IF it is NULL (worst case happens), it will stop the application and throw a bug to you to locate it.

Use this version of the assert statement to provide a detail message for the AssertionError. The system passes the value of Expression2 to the appropriate AssertionError constructor, which uses the string representation of the value as the error's detail message.
The purpose of the detail message is to capture and communicate the details of the assertion failure. The message should allow you to diagnose and ultimately fix the error that led the assertion to fail. Note that the detail message is not a user-level error message, so it is generally unnecessary to make these messages understandable in isolation, or to internationalize them. The detail message is meant to be interpreted in the context of a full stack trace, in conjunction with the source code containing the failed assertion.
JavaDoc

Assertions are generally used primarily as a means of checking the program's expected behavior. It should lead to a crash in most cases, since the programmer's assumptions about the state of the program are false. This is where the debugging aspect of assertions come in. They create a checkpoint that we simply can't ignore if we would like to have correct behavior.
In your case it does data validation on the incoming parameters, though it does not prevent clients from misusing the function in the future. Especially if they are not, (and should not) be included in release builds.

It ensures that the expression returns true. Otherwise, it throws a java.lang.AssertionError.
http://java.sun.com/docs/books/jls/third_edition/html/statements.html#14.10

Assert does throw an AssertionError if you run your app with assertions turned on.
int a = 42;
assert a >= 0 && d <= 10;
If you run this with, say: java -ea -jar peiska.jar
It shall throw an java.lang.AssertionError

Related

What is the best way to check null in Java [duplicate]

This question already has answers here:
object==null or null==object?
(11 answers)
Closed 5 years ago.
When checking for nulls I use this:
String str;
if(str == null){
//...
}
but I've seen this as well:
if(null == str){
//...
}
Is there any advantage of using one over the other? Or is it just to improve readability?
The second version ( null == str ) is called a yoda condition.
They both result in the same behavior, but the second one has one advantage: It prevents you from accidentally changing a variable, when you forget one =. In that case the compiler returns an error at that row and you're not left with some weird behavior of your code and the resulting debugging.
The null == x convention is usually found in code written by people familiar with C, where an assignment can also be an expression. Some C programmers write code like this so that if they miss an = in
if (NULL == ptr)...
the code will not compile, since NULL = ptr is not a valid assignment. This prevents a rather sneaky error from being introduced in the code-base, although modern C compilers make make such conventions obsolete, as long as one takes care to enable and read the generated warnings...
This coding style has never had any usefulness in Java, where reference assignments cannot be used as boolean expressions. It could even be considered counter-intuitive; in their natural language most people will say "if X is null...", or "if X is equal to 17...", rather than "if null is equal to X...".
There's no difference between the two other than readability. Use whichever makes more sense to you.
As you stated readability is the most important reason. Reading it out loud, the (null == str) does not read well. It's almost like reading right to left. (str == null) reads much better.
In addition, I think the following needs to be taken into consideration:
if (str != null)
if (str == null)
vs.
if (null != str)
if (null == str)
I would expect the positive (str == null) and the negative to be written in the same manner, which is another reason I would favor the top set.
if (null == str) {
}
is a programming idiom from c/c++, where the assignment operator = can be used to resolve to a true/false statement. For example in c if you want to check if I can open a stream in c/c++, you can
if (myStream = openStream())
which sets opens and assigns in one line. However, this means that people often type = when they mean ==, and it would be valid syntax in c: for example if (x = 5) will always resolve to true, when they really mean if (x ==5). So people write if (5 == x) so if you leave out a = your code won't compile.
This doesn't apply to java.
There is no real difference. However the second is considered less error prone. In the first case you would not get an error if you tried to do
String str;
if(str = null){
}
which is something you usually don't do in conditionals.
Also, you get to think about the actual condition first, which is a good practice.
if(a==b) {} is the same as if(b==a) {} , and the same is true if b was null. It's just a style/order difference as far as functionality, at least in java.
Some developers argue that var == null is more error-prone than null == var. Their argument is that you might accidentally assign the variable instead of doing a null-check.
But only when the variable you test against null is a Boolean you can accidentally use the = instead of == and it will compile.
Boolean checked = Boolean.TRUE;
if(checked = null){ // accidentally assigned null and compiles
}
Only in this case the assignment compiles, because the conditional expression must evaluate to a boolean value. See JLS-14.9. Since the assignment expression itself evaluates to a boolean type, it compiles. But you will get a NullPointerException at runtume, because java will try to unbox the checked variable which is null.
If you use any other type then Boolean you will get a compiler error. E.g.
String str = "hello";
if(str = null){ // compiler error, because str = null doesn't evaluate to a boolean
}
My conclusion is that error situations are extremly rare and you can easily write unit tests that detect such errors.
So write the if-statement it in the way it is more readable.
I think "if name is null" makes more sense then "if null is name".

Checking for null - what order? [duplicate]

This question already has answers here:
object==null or null==object?
(11 answers)
Closed 5 years ago.
When checking for nulls I use this:
String str;
if(str == null){
//...
}
but I've seen this as well:
if(null == str){
//...
}
Is there any advantage of using one over the other? Or is it just to improve readability?
The second version ( null == str ) is called a yoda condition.
They both result in the same behavior, but the second one has one advantage: It prevents you from accidentally changing a variable, when you forget one =. In that case the compiler returns an error at that row and you're not left with some weird behavior of your code and the resulting debugging.
The null == x convention is usually found in code written by people familiar with C, where an assignment can also be an expression. Some C programmers write code like this so that if they miss an = in
if (NULL == ptr)...
the code will not compile, since NULL = ptr is not a valid assignment. This prevents a rather sneaky error from being introduced in the code-base, although modern C compilers make make such conventions obsolete, as long as one takes care to enable and read the generated warnings...
This coding style has never had any usefulness in Java, where reference assignments cannot be used as boolean expressions. It could even be considered counter-intuitive; in their natural language most people will say "if X is null...", or "if X is equal to 17...", rather than "if null is equal to X...".
There's no difference between the two other than readability. Use whichever makes more sense to you.
As you stated readability is the most important reason. Reading it out loud, the (null == str) does not read well. It's almost like reading right to left. (str == null) reads much better.
In addition, I think the following needs to be taken into consideration:
if (str != null)
if (str == null)
vs.
if (null != str)
if (null == str)
I would expect the positive (str == null) and the negative to be written in the same manner, which is another reason I would favor the top set.
if (null == str) {
}
is a programming idiom from c/c++, where the assignment operator = can be used to resolve to a true/false statement. For example in c if you want to check if I can open a stream in c/c++, you can
if (myStream = openStream())
which sets opens and assigns in one line. However, this means that people often type = when they mean ==, and it would be valid syntax in c: for example if (x = 5) will always resolve to true, when they really mean if (x ==5). So people write if (5 == x) so if you leave out a = your code won't compile.
This doesn't apply to java.
There is no real difference. However the second is considered less error prone. In the first case you would not get an error if you tried to do
String str;
if(str = null){
}
which is something you usually don't do in conditionals.
Also, you get to think about the actual condition first, which is a good practice.
if(a==b) {} is the same as if(b==a) {} , and the same is true if b was null. It's just a style/order difference as far as functionality, at least in java.
Some developers argue that var == null is more error-prone than null == var. Their argument is that you might accidentally assign the variable instead of doing a null-check.
But only when the variable you test against null is a Boolean you can accidentally use the = instead of == and it will compile.
Boolean checked = Boolean.TRUE;
if(checked = null){ // accidentally assigned null and compiles
}
Only in this case the assignment compiles, because the conditional expression must evaluate to a boolean value. See JLS-14.9. Since the assignment expression itself evaluates to a boolean type, it compiles. But you will get a NullPointerException at runtume, because java will try to unbox the checked variable which is null.
If you use any other type then Boolean you will get a compiler error. E.g.
String str = "hello";
if(str = null){ // compiler error, because str = null doesn't evaluate to a boolean
}
My conclusion is that error situations are extremly rare and you can easily write unit tests that detect such errors.
So write the if-statement it in the way it is more readable.
I think "if name is null" makes more sense then "if null is name".

what does the keyword assert means in java?

i saw somewhere in GWT code , it was something like this
assert display instanceof Widget : "display must extend Widget";
The assert keyword, as the name implies, makes an assertion about the code. It is used to specify something that holds true all the time -- or that, at least, should be true!
The assert keyword is followed by a boolean value (true or false), or an expression, to be evaluated at runtime, that returns a boolean.
assert true;
assert 1 == 1;
If, for any reason, the boolean expression evaluates to false, then an AssertionError is thrown.
// this will throw an AssertionError:
int x = 1;
assert x == 2;
When you use it, you make a clear statement about the state of your program on a given point, which can make it easier for readers to follow through your code.
There's a programming paradigm called program by contract, in which pieces of code make statements about the pre-conditions that must hold true for them to execute properly, and the post-conditions, that are guaranteed to hold true after their execution. You can use the assert keyword to implement this.
For example, if you write a method that calculates the square root of a number, it will only work for numbers that are greater than or equal to zero, and the result is guaranteed to satisfy the same conditions:
public double sqrt(final double x) {
assert x >= 0 : "Cannot calculate the square root of a negative number!"
double result = ...;
assert result >= 0 : "Something went wrong when calculating the square root!"
return result;
}
The most interesting aspect of assertions is that you can ask the compiler to remove them from the bytecode (by means of the -disableassertion argument), so that you won't get any kind of performance penalty at runtime on production. For this precise reason, it is of fundamental importance that the expression to be evaluate does not cause side-effects, that is, the expression should look like a pure mathematical function. Otherwise, the behavior of your program could change if the compiler removed your assertions.
Finally, if the assertions are compiled into the bytecode, they can be read by a software that will automatically generate tests that will try to break your code. It can be useful to find bugs earlier!
The assert keyword was introduced in 1.4 (follow that link for a complete description). It is a shorthand to throw an exception at runtime if a condition is not satisfied.
Think of it as
assert condition : message
as
if ( ! condition ) {
throw new AssertionError ( message ) ;
}
The idea is to give developers an easy way to help users (in your case GWT API users) to detect common errors/pitfalls
When it was introduced, the assert statement became a reserved word and that caused a few compilation issues when old code was recompiled for I.4. Especially for JUnit test suites where there was a much used assert() method. JUnit reacted by replacing assert with assertTrue()
It means that if display isn't an object of type Widget, you'll get an AssertionError with the text string that follows the assertion. Assertions are helpful for debugging.
assert keyword is used to simplify the userdefined exception.what happens,to define a userdefined exception we have to create our own exception class by defining the exception causing condition first then we have to throw that in our program.
but from java 1.5 onwards we have a keyword as assert where only we have to write assert(condition) if condtion is true it executes the other part of the program or else if it is false the it creates the object of AssertionError class and we have to handle it.
so no need to define our userdefind error.
The following text (emphasis mine) explains various forms of assertions clearly:
The assertion statement has two forms.
The first, simpler form is:
assert Expression1 ;
where Expression1 is a boolean expression. When
the system runs the assertion, it evaluates Expression1 and if it is
false throws an AssertionError with no detail message.
The second form of the assertion statement is:
assert Expression1 : Expression2 ; (Your example falls here)
where: Expression1 is a boolean expression. Expression2 is an expression that
has a value. (It cannot be an invocation of a method that is declared
void.) Use this version of the assert statement to provide a detail
message for the AssertionError. The system passes the value of
Expression2 to the appropriate AssertionError constructor, which uses
the string representation of the value as the error's detail message.
Also, refer the following oracle link for detailed information:
http://docs.oracle.com/javase/7/docs/technotes/guides/language/assert.html

bad java compiler optimization?

I have this piece of code:
private void prepareContent() {
log.info("do something");
// success?
boolean suc = false;
suc = suc || uncompressToContent("file.tar.gz");
suc = suc || uncompressToContent("file.tgz");
for (int i = 0; i <= 9; i++) {
suc = suc || uncompressToContent("dir/" + i + ".tgz");
suc = suc || uncompressToContent("dir/" + i + ".tar.gz");
}
if (!suc) {
log.error("unable to do something");
}
}
The function returns false for "file.tar.gz" and file.tgz".
The problem is the the call to uncompressToContent("dir/1.tgz") returns true and the code stops its execution. The remaining code is not executed.
I'm not sure if this is an error in the compiler. What do you think?
Added: I forgot to mention that I need to execute all the calls to uncompressToContent and check if any returns true, using the fewer instructions as possible.
There is no error in the compiler.
As soon as suc is set to true (i.e. from the first uncompressToContent call) then all of the future expressions will return true without calling uncompressToContent. This is becuase you are using short circuit boolean or ("||") which do not evaluate the second argument if the first argument is true.
If you want all the calls to be made, use the normal or operator ("|") instead.
If the uncompress method returns true if there was a successful decompression, then suc would become true the first time that this happens. Once suc is true, all the other conditions would be true as soon as suc is evaluated, so the other part of the OR would not be evaluated. Thus, no decompressions will be attempted once at least one is successful.
This is called short circuiting and is the correct behavior and is a very useful property in most languages. And is also not a compiler optimization since it is part of the defined behavior of the language.
Beyond this answer, there are, I think, ways to make this code more readable.
First, are you sure that you want to OR rather than AND here? It seems like you want to quit as soon as one file did not compress decorrectly, not stop as one did decompress correctly.
Second, a better design, IMHO, would be to create a list of all the filenames you want to decompress, and then do a for-each over that list and do all the decompressions, it would make things more readable.
Third, if in most cases decompression would be successful, I think that exception handling is much better than boolean return values.
Here is how I would write something like this (and I would break it into functions)
List<String> filenames = new ArrayList<String>();
this.collectFilenamesToDecompress(filenames) // Write one or more than one functions of this sort based on the semantics of your problem
try
{
for(String filename: filenames)
{
uncompressFile(filename); // This will throw an exception if there is a failure
}
} catch(Exception e)
{
// Announce that there was an error and you stopped decompressing because there was an error.
// Return or quit
}
// If you got here, everything is great!
This behavior is by design.
Logical operators in most languages are short-circuiting.
In the expression a || b, b will only be evaluated if a is false.
Therefore, once suc becomes true, none of the other calls to uncompressToContent will be evaluated.
I think the compiler is doing something like: suc = uncompressToContent("file.tar.gz") || uncompressToContent("file.tgz") || uncompressToContent("...") || ... So, when it finds one true value, the execution is stopped. Is this feature documented?
Yes. It is clearly documented in the Java Language Specification section 15.24, where it says this:
"The || operator is like | (§15.22.2), but evaluates its right-hand operand only if the value of its left-hand operand is false."
The JLS then goes on to explain exactly what happens in excruciating detail. Follow the link above if you are interested.
Oh yea, and in this respect the Java || operator behaves the same as in C, C++, C#, Perl and many other programming languages.

What is the proper error message to supply to Google Guava's Preconditions.* methods?

For example when using Preconditions.checkArgument, is the error message supposed to reflect the passing case or the failing case of the check in question?
import static com.google.common.base.Preconditions.*;
void doStuff(int a, int b) {
checkArgument(a == b, "a == b");
// OR
checkArgument(a == b, "a != b");
}
For precondition checks, stating the requirement in the exception detail message is more informative than simply stating the facts. It also leads to a lot more naturally reading code:
The documentation provides the following example:
This allows constructs such as
if (count <= 0) {
throw new IllegalArgumentException("must be positive: " + count);
}
to be replaced with the more compact
checkArgument(count > 0, "must be positive: %s", count);
Two things are of note:
The example clearly states requirement, rather than the fact
"something must be right", instead of "something is wrong"
By inverting the condition of the check, the entire construct read more naturally
Following that example, a better message would be:
checkArgument(a == b, "a must be equal to b"); // natural!
You can even go a step further and capture the values of a and b in the exception message (see Effective Java 2nd Edition, Item 63: Include failure capture information in detail messages):
checkArgument(a == b, "a must be equal to b; instead %s != %s", a, b);
The alternative of stating facts is less natural to read in code:
checkArgument(a == b, "a != b"); // awkward!
checkArgument(a == b, "a is not equal to b"); // awkward!
Note how awkward it is to read in Java code one boolean expression, followed by a string that contradicts that expression.
Another downside to stating facts is that for complicated preconditions, it's potentially less informative, because the user may already know of the fact, but not what the actual requirements are that is being violated.
Related questions
Null check error message as “is null” or “was null”
The documentation gives examples which make it very clear using words instead of symbols:
checkArgument(count > 0, "must be positive: %s", count);
Given that these are basically just going to be exception messages in logs (or debugging sessions), do whatever you think will make it clearest to anyone looking at problem, or anyone reading the code to understand the precondition.
For example, you could rewrite the above as:
checkArgument(count > 0, "count must be positive; was actually %s", count);
Personally, for something like this I think I'd write
checkArgument(a == b, "a (%s) must equal b (%s)", a, b);
Often (most of the time) you can just use the checkArgument() method without the error message parameter, that is, not supplying the error message at all.
To make a good error message one needs to understand who will read the message. It is not the end-user; if the precondition fails it points most likely to a bug in the code. The text may explain the failed precondition, but in most cases it is of no use to the end-user, it is supposed to be a hint for the programmer. Most of the time, the message by itself also makes no sense without a stacktrace and source code. In fact, in most cases, a stacktrace and source code is exactly what a programmer needs to fix a bug, the error message doesn't help. If the precondition is not obvious, a comment next to it is a perfect way to document it.
The need to always supply an error message in cases no one really cares about the text leads to programmers making useless, obvious and not helpful messages which only makes the code less readable.
There are some cases, when an error message can be useful, for instance the message can contain the actual values of variables, but from our experience that is not very often, and in these cases you can use the message.
Similar arguments apply also in the assert methods in JUnit; always providing an error message is not a good idea.
Also, when you are using preconditions in a library rather than an application for end-users, things might be different since you don't know how your code will be used.
As polygenelubricants pointed out:
For precondition checks, stating the requirement in the exception detail message is more informative than simply stating the facts.
While you can certainly do this with Guava Preconditions, Requirements API (which I authored) allows you to achieve better output without any effort on your part.
Guava Preconditions
String a = "foosball";
String b = "ballroom";
Preconditions.checkArgument(a == b, "a == b");
gives you this:
java.lang.IllegalArgumentException: a == b
at com.google.common.base.Preconditions.checkArgument(Preconditions.java:122)
at Main.main(Main.java:142)
Requirements API
String a = "foosball";
String b = "ballroom";
requireThat(a, "a").isEqualTo(b, "b")
gives you this:
Same input, better output.
(If your terminal does not support colors, you will get a textual diff instead)

Categories