I was trying to write a simple method:
boolean validate(MyObject o)
{
// propertyA && propertyB are not primitive types.
return o.getPropertyA() == null && o.getPropertyB() == null;
}
And got a strange error on the == null part:
Syntax error on token ==. Invalid
assignment operator.
Maybe my Java is rusty after a season in PLSQL. So I tried a simpler example:
Integer i = 4;
i == null;
// compile error: Syntax error on token ==. Invalid assignment operator.
Integer i2 = 4;
if (i == null); //No problem
How can this be?
I'm using jdk160_05.
To clarify: I'm not trying to assign anything, just do an && operation between two boolean values. I don't want to do this:
if (o.propertyA() == null && o.propertyB() == null) { return true; }
else { return false; }
== is not an assignment operator, it's a boolean equality operator, see:
http://java.sun.com/docs/books/jls/third_edition/html/expressions.html#15.21.2
If you want to set i to null use the simple assignment operator =:
i = null;
http://java.sun.com/docs/books/jls/third_edition/html/expressions.html#15.26.1
If you want to check that i is null then you need to use the == operator
if (i == null)
I don't think you are confusing assignment and equality comparison. I think your compiler is just giving you a confusing error message. This program:
Integer i = 4;
i ==null;
should give an error something like this:
Program.java:8: not a statement
i ==null;
Your first program should compile correctly. Perhaps there is some invisible unicode character in the text that is confusing the compiler. Try deleting the entire function and typing it in again.
I think I see your problem. I'm sorry the other answers don't address it.
So, Java has this idea that is shared by some other languages that just because something is a valid expression doesn't mean that that thing, by itself, is a valid statement.
For example, this code will complain similarly:
Integer i = 4;
i+3; // this line gives a compilation error
And yet obviously I can use i+3 (go unboxing!) elsewhere to mean "7":
System.out.println(i+3); // this is fine
It gets a bit confusing because unlike some languages that have this expression/statement distinction, java allows you to use any method call - whether it returns a value or not - as a statement. However, most java operators do not - by themselves - form a valid statement.
Likewise, this fails to compile:
Integer i = 4;
i; // this line gives a compilation error
For the full gory details, see http://java.sun.com/docs/books/jls/second_edition/html/statements.doc.html#32588
In PL/SQL, assigning a value to a variable is done with the := operator. Comparing two values is done with =.
In Java, assigning a value to a variable is done with the = operator. Comparing two values is done with ==, or a .equals() method in some cases.
You can do things like this:
x = i==null;
This will test if i is null and if so, the value true will be assigned to x (assuming that x is a boolean).
Related
I have a piece of code that uses a conditional operator to compare the value of the variable x to 5:
(x >=5 ? x : -x)
What benefit is there to using a conditional operator over a regular if else statement?
Note that is ?: is an expression - it returns a value which must be consumed
z = (x >=5 ? x : -x)
The if construct in Java is not an expression (there are languages where it is) and does not return a value so in this sense they are not equivalent.
An example where they are equivalent is when the if options perform an assignment:
if("Cheese".equals(x)) {
type = "Dairy";
} else {
type = "Maybe not dairy";
}
this is the same as
type = "Cheese".equals(x) ? "Dairy" : "Maybe not dairy";
You can nest ?: to arbitrary depth but really shouldn't - it becomes quite difficult to read:
List<String> cheeses = Arrays.asList("Gouda", "Edam");
String x= "Gouda";
String type = cheeses.contains(x) ? "Gouda".equals(x) ? "Yummy Gouda" : "Cheese - but not Gouda" : "Maybe not dairy";
Ternary operator is not the equivalent of if-else in EVERY possible case. This is because both of possible results of using ternary operator are return values (e. g. simple printing to the console is not a return value so it can't be one of possible results in ternary operator).
Look, you can do it with if-else, but it's not possible with ternary operator:
if (x > 5) {
System.out.println("Statement is true");
else {
System.out.println("Statement is false");
}
You can't do it with ternary operator:
x > 5 ? System.out.println("Statement is true") : System.out.println("Statement is false");
When both of results of using ternary operator are considered as return values, they are then an equivalent of if-else.
Yes, it can be used, but off course in that case using -x doesn't make sense so it depends on what do you want to return when String is an input. You can do this:
("Cheese".equals(x) ? <some object of expected type X> : <some other object of expected type X>)
where X can be String on any other type. And remember to do "string".equals(x) instead of x.equals("string"). This prevents NullPointerException.
For primitive values you can use ==, but for objects you need to use equals method. There are some edge cases when you can use == on String, but they are not relevant to your case I guess and you can read about it outside of this topic.
PS: Some answers talk about if else statement, but that's not what question is about.
Can this be used like an if else on all accounts? For example, can you
compare strings with it?
I am pretty sure that by saying like an if else he means conditional operator which has if else like behaviour, not if else instruction itself.
Yes it can be used in Java; however note that x =="Cheese" isn't the proper way to compare strings in Java, you want something like "Cheese".equals(x).
I am facing something strange here. Please help me understand if I am missing something. My if condition was supposed to be:
if(configuredPdf == true)
But by mistake I had written:
if(configuredPdf = true)
And my Eclipse compiler does not ask me to correct it. Then I assume there is no compile time or checked exception. So:
(configuredPdf = true)
Returns a boolean?
Yes, configuredPdf = true assigns true to your variable and returns true. Therefore if (configuredPdf = true) is a valid syntax even though it's usually a bug.
It's safer to use if (configuredPdf) to avoid this kind of typo.
An assignment is an expression which returns the value you assigned. e.g. a = b = true will assign true to a and b.
The reason boolean type was added was to avoid this sort of bug. In C for example you can write
if (a = 1)
and anything non-negative is true.
While you can still make a mistake with boolean types, instead of writing
if (a == true)
if (b == false)
you can write
if (a)
if (!b)
A more common example is
for(String line; ((line = br.readLine()) != null;) {
// process the line.
}
An assignment expression's result is always the value that was assigned, including when assigning to a boolean. This is covered by JLS§15.26:
At run time, the result of the assignment expression is the value of the variable after the assignment has occurred.
So yes, configuredPdf = true assigns true to configuredPdf, and the result of that expression is true.
Similarly, x = y = 5; assigns 5 to y, and the result of y = 5 is 5, which is then assigned to x.
Fundamentally, what you wanted was:
if (configuredPdf)
There's never any need to compare a boolean variable with true or false, just use the if (theVariable) (for comparing with true) or if (!theVariable) (for comparing with false). Getting in that habit will protect you from inadvertent assignment.
The only time actually comparing boolean values is useful is when they're both variables, e.g. if (thisFlag == thatFlag) or if (thisFlag != thatFlag).
To avoid accidental assignment in that situation, either:
Use a linter that checks for this
"double bang" the first flag:
if (!!thisFlag == thatFlag)
...although as you pointed out if you can accidentally type = instead of ==, presumably you can accidentally type ! instead of !! :-)
Use an old C idiom (this is what I use):
if (!thisFlag == !thatFlag)
What is happening is when the compiler comes to the if condition in your code, it assigns 'configuredpdf' to be true. Thus the condition
if(configuredpdf = true)
Becomes true and the loop executes successfully. However, the problem arises when we DON'T want this loop to be true. At that time when, for a given input, the compiler parses the if condition, it forcibly becomes true and executes the code written in if condition executes even if the data entered does not agreeing. That is why you will find that your code has a bug at the if condition.
configuredPdf must be a boolean for if(configuredPdf = true) to compile.
configuredPdf = true will assign true to configuredPdf and thus if will succeed.
I wrote a line to add a total up the total value
int totalValue = value1 + value2 + value3;
Now I want to use an if statement to write if (totalValue = 200); but it gives me an error saying "Cannot convert from an int to a boolean type".
What should I do because I want to have four possible outcomes using else if();
System.out.println();
if (totalValue == 200)
= is for assigning values, == is for comparing values.
The = operator in Java only does assignment; you want to compare totalValue to 200, so you should use the == comparator operator.
if(totalValue = 200){
...
}
Do note that you shouldn't have a semicolon after an if statement, since then Java will basically ignore the if.
The = sign is the assignment operator.
Doing if(totalValue = 200) will actually assign 200 to totalValue.
What you need is the == operator
if(totalValue == 200)
{
System.out.println("200");
}
else if (totalValue == 100)
{
System.out.println("100");
} //...
Putting the line terminator at the end of if(totalValue == 200);
will terminate the conditional statement. This means that the statements below it will not only execute if the condition evaluates to true.
Also, I find it good practice to always put {} after the if() even with just one statement to prevent issues with scoping. Here's a link to show how this can happen (and prevented) https://stackoverflow.com/questions/21999473/apples-goto-fail-security-bug
if you write if(totalValue = 19), it will evaluate if you can successfully assign 19 to totalValue.
Being successful or not, in Java is a Boolean, so it expects to evaluate a boolean.
The expression:
if((totalValue = 19) == True){ ... }
would be correct but also useless, in this case, because it will almost for sure assign successfully the value
if you wanna only check the value you must use ==
Yes, but equality is == and assignment is =. Also, don't end your if statement with a semicolon or you terminate the body of the if.
// if (totalValue = 200);
if (totalValue == 200) {
// Do stuff for when the value is 200
} else {
// Do stuff when the value is not 200
}
Like the others said, the '=' operator in Java is used to assign values. However (maybe a little off-topic), the assignment itself evaluates to the assigned value, which can be reused in a boolean expression.
This can be used like in this loop, where the result of readLine is stored and compared to null in a single expression:
int value;
while ((value = reader.read()) != -1) {
doSomething(value);
}
Why does java require a double equals sign (==) when comparing Integers in a if statement?
For example
if(x = 3.141)
System.out.println("x is equal to pi.");
is incorrect, it should be
if(x == 3.141)
System.out.println("x is equal to pi.");
I know that "==" is used to compare integers and "=" is used to set an integer value, but why in a if statement does this remain true?
Is it even allowed to assign a variable a value in an if statement (or initiate a new variable)?
Is there any reason anyone would ever want to assign a variable a new value inside an if statement (if so please provide an example)?
This seems like a question that should already have an answer, but I was unable to find one on here or using google, if this is a duplicate question please tell me and I will remove it immediately.
Wouldn't it be confusing if = sometimes did assignment, and sometimes comparison, depending in which context you used it?
That sounds like a bad idea, and would introduce errors.
Plus, the current syntax is compatible with C and C++, so a lot of people are familiar with it.
Is there any reason anyone would ever want to assine a variable a new value inside of an if statement (if so please provide an example)?
It's quite common in while loops:
int b;
while ((b=in.read()) != -1){
=
is used for assignment.
==
is used for comparison.
Is it even allowed to assign a variable a value in an if statement (or initiate a new variable)?
yes it is allowed.
Note what error message you get for if (x = 3.141); it is a type error (cannot convert from double to boolean).
The assignment's type is the type of its both sides; if the type of the assignment is boolean (if (x = true), or even if (x = a.equals(b))), then it is legal to write.
So since it is legal to assign a value to a boolean in the condition, you'd have to use == for comparison.
Is it even allowed to assine a variable a value in an if statement (or initiate a new variable)?
Yes. A common idiom for doing this is:
String line = null;
while ( (line = in.readLine()) != null ) {
// do work
}
In the loop, line is assigned a value and then compared to null. I can't think of an example with ints; it certainly wouldn't be clear there.
History of programming languages 101:
Fortran uses = for both.
Algol introduced := for assignment and used = for comparison. This was required to resolve a grammar ambiguity.
Pascal followed suit.
PL/1 did not.
I can't speak for B or BCPL but by the time we got C it was = for assignment and == for comparison, again to resolve a grammar ambiguity
C++ followed C
Java followed C++ in many respects including this one.
The grammar ambiguity arises because of allowing assignments in expressions. Contrary to your assertion, if (x = true) is legal in Java if x is of type boolean.
== is the identity comparator, which works for both objects and primitives. It answers the question "are the two things the same thing".
= is the assignment operator. It sets the value of the left side to the right side.
Things can turn buggy when using your example with booleans:
boolean b;
if (b = true) // This compiles, but is a bug, because it sets b, not tests it
While other types won't compile with this syntax, boolean and Boolean do, so that's why the following pattern is advised:
if (b)
you can absolutely assign a variable in an if statement. also, that's just the way it works: = always is assignment, and == is always comparison.
So..
= is assignment, and == is comparison, and it is always like this, no matter where they are used.
And assignment is different with "declaration". An assignment statement has its return value, while a declaration doesn't. So you can't write boolean a = false in the () of if statement, but you can write a = false when a has been declared before.
Not all assignments are legal. For example:
int index;
if (index = str.indexOf("something")) {
...
}
It's not legal, because String.indexOf(String) returns an int, while if requires a boolean.
Also, there is a huge difference between "legal" and "making sense".
int index;
if ((index = str.indexOf("something")) != -1) {
...
}
It is legal, as != operation returns a boolean, and it makes sense, as I do want to check if the str contains a substring "something";
However,
int index;
boolean flag;
if ( flag = ((index = str.indexOf("something")) != -1) ) {
...
}
is also legal, as the statement as last returns a boolean; but it DOESN'T make sense, because the != statement already returns a boolean.
Currently I'm using:
int a=10;
if(a=20)
printf("TRUE");
else
printf("false");
Which prints, in C, the value TRUE.
But in case of java:
int a=10;
if(a=20)
System.out.println("TRUE");
else
System.out.println("FALSE");
I'll get a compile time error about an incompatible type.
The reason for that is that in C there is no specific type boolean - instead any non-0 integer evaluates to a boolean "true". Thus in your C code:
if(a=20)
a is assigned the value 20, which is non-0 - and the condition is evaluated as true
In java, there's a fundamental type boolean and the value of the conditional inside if must be of this type.
a=20
in Java assigns 20 to a and returns the final result of evaluation as integer value 20, however type boolean is expected - hence you're getting a compile-time error about the incompatible types.
If you want to do a comparison of a with 20, however, you need to use == operator both in C and Java:
if(a == 20)
This will compile in both C and Java and print FALSE in both languages.
You need to replace = with ==.
= is an assignment operator
int a=10;
if(a==20){
System.out.println("TRUE");}
else{
System.out.println("FALSE");}
This should work fine.
Edit:
In C, the returned integer value of the assignment (in this case 20) is a positive int, which evaluates to true.
In java, a boolean is expected.
(See the more thorough answer provided by Aleks G)
A single = is an assignment. If you want to test for equality, you use the double == in both C and Java.
It should be evident that you're doing the wrong thing, even in the C version, since you set a to 10 and then, on "comparing" it to 20, you get a true value. I'm not aware of any mathematical systems where 10 and 20 are considered equal :-)
What happens in your C case is that the assignment actually "returns" a value as well.
The statement:
if (a = 20) ...
is equivalent to:
a = 20;
if (a) ...
so it first sets a to 20, then uses that as the if condition. Since 0 is false and anything else is true, the body of the if is executed.
A good compiler (like gcc) will actually warn you of what you're doing so that you don't get caught out by these little things. Some people also use the trick of putting constants first:
if (20 == a) ...
so that, if you mistakenly use assignment, it's a syntax error. But I find that sort of code ugly, especially since I mostly use those good compilers mentioned above :-)
The reason you get an error in Java is because it's much more strict on what you can do with assignments. By that, I mean there is no automatic conversion from int to boolean as with C. So this code refuses to compile, producing an error:
class Test {
static public void main(String[] args) {
int a = 10;
if (a = 20)
System.out.println ("true");
}
}
But you can still get burnt with something like this:
class Test {
static public void main(String[] args) {
boolean a = false;
if (a = true)
System.out.println ("true");
}
}
Because that assignment is of a boolean value inside the if, it doesn't cause a compilation error due to the wrong type. However, since it prints true, it's still not what you wanted.
Bottom line, go back an re-read that first paragraph. = is assignment, == is equality checking.
Use the == to test the condition instead of =. That way, you are assigning 20 to a and not testing for a condition.
if (a==20) ... or
System.out.println(a==20);
value of a=20 is 20. You should use == operator.
for comparison you should use ==
if(a==20) instead of a=20, which is assignment