when using equals method with a null string...

M

minjie

If I have declared 2 strings as follows:
private String myStr1 = "";
private String myStr2 = "";
and somewhere in the application they may or may not get assigned
values. When I do
if (myStr1.equals(myStr2))
....
I will get an exception if myStr1 is null. How do I test it without
using
if (myStr1 != null)
if (myStr1.equals(myStr2))
....
?
I have a lot of string comparisons like the above, and if I have to
test one by one like that, it's a lot of code!
Thanks.
 
T

Tony Burrows

If I have declared 2 strings as follows:
private String myStr1 = "";
private String myStr2 = "";
and somewhere in the application they may or may not get assigned
values. When I do
if (myStr1.equals(myStr2))
....
I will get an exception if myStr1 is null. How do I test it without
using
if (myStr1 != null)
if (myStr1.equals(myStr2))
....
?
I have a lot of string comparisons like the above, and if I have to
test one by one like that, it's a lot of code!
Thanks.
You're relying on an optimising String creation. Java sees there is no
content, so doesn't actually bother to create a String object. Using
thi approach, if two strings have the same content, then Java stores just
one.

String myStr1 = "one";
String myStr2 = "one";
will create just one String, with two references to it, for the
sake of efficiency. This means equals and == will both report true.

On the other hand, you can force Java to create one string object per
variable, by using new.

myStr1 = new String(""); creates a real String object, and then you can
call equals on it.

Tony
 
M

mike

The first thing that comes to my head is to write your own method that
will do the above. For example:

boolean equals(String a, String b) {
if (a != null)
return a.equals(b);
else
return false;
}

that would save you on the typing. Other than that, I don't see a
better way.

Mike
 
E

Ed Kirwan

If I have declared 2 strings as follows:
private String myStr1 = "";
private String myStr2 = "";
and somewhere in the application they may or may not get assigned
values. When I do
if (myStr1.equals(myStr2))
....
I will get an exception if myStr1 is null. How do I test it without
using
if (myStr1 != null)
if (myStr1.equals(myStr2))
....
?
I have a lot of string comparisons like the above, and if I have to
test one by one like that, it's a lot of code!
Thanks.

You could use a library, for example:

class Library {
boolean isEqual(String a, String b) {
if (a == null) {
return false;
} else {
return a.equals(b);
}
}
}

(Adjust to suit to case a and b both are null.)

At least then your code would only peppered with:
if (Library.getInstance().isEqual(a, b)) {
....
}
 
T

Tony Burrows

If I have declared 2 strings as follows:
private String myStr1 = "";
private String myStr2 = "";
and somewhere in the application they may or may not get assigned
values. When I do
if (myStr1.equals(myStr2))
....
I will get an exception if myStr1 is null. How do I test it without
using
if (myStr1 != null)
if (myStr1.equals(myStr2))
....
?
I have a lot of string comparisons like the above, and if I have to
test one by one like that, it's a lot of code!
Thanks.
I've just tried this code in Java 1.4 and 1.5
public class testCode{
public static void main (String[] args){
String s = "";
String y = new String("");
System.out.println("Tony equals string y"+ y.equals("Tony"));
System.out.println("Tony equals string s"+ s.equals("Tony"));
}
}
and it compiles and runs with no problems. I don't get a null pointer at
all. I can't get one with an if statement either.

Tony
 
N

njzy333

Hello Tony,
That is strange. The difference between your code and my code is that I
declared both strings to be private, and neither are NEWed. I changed
my code according to your example, and I'm still getting an exception.
I guess there is a slight difference in our environment or libraries?
I'm using NetBeans with Java 1.5.
Thanks.
 
O

Oliver Wong

Hello Tony,
That is strange. The difference between your code and my code is that I
declared both strings to be private, and neither are NEWed. I changed
my code according to your example, and I'm still getting an exception.
I guess there is a slight difference in our environment or libraries?
I'm using NetBeans with Java 1.5.
Thanks.

Try running Tony's code exactly as is. If you're getting NPEs, then your
Java is broken, and you should uninstall it, redownload it, and reinstall
it.

- Oliver
 
H

Hendrik Maryns

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
NotDashEscaped: You need GnuPG to verify this message

(e-mail address removed) schreef:
Hello Tony,
That is strange. The difference between your code and my code is that I
declared both strings to be private, and neither are NEWed. I changed
my code according to your example, and I'm still getting an exception.
I guess there is a slight difference in our environment or libraries?
I'm using NetBeans with Java 1.5.

Learn the difference between null and "". "" will not throw an NPE if
you invoke methods on it. See http://mindprod.com/jgloss/string.html,
the part about comparison and gotchas.

H.
--
Hendrik Maryns

==================
www.lieverleven.be
http://aouw.org
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.2 (GNU/Linux)

iD8DBQFEEa86e+7xMGD3itQRAvD9AJoD/32bPrkTf7IL7+RzI1C/MRYSdwCfc4F9
JQEz0IvI5kQOKHpd98ZVayA=
=ow03
-----END PGP SIGNATURE-----
 
B

Boobay

Please read the documentation over NullPointer exceptions. You should
be able to use a try catch block and eliminate/track down the problem
you're having with your code.
 
T

Thomas Hawtin

if (myStr1.equals(myStr2))
....
I will get an exception if myStr1 is null. How do I test it without
using
if (myStr1 != null)
if (myStr1.equals(myStr2))
....

It is normal to use -

if (myStr1 != null && myStr1.equals(myStr2)) {

If you know that myStr2 will never be null, you can just turn it around
(often used with literals) -

if (myStr2.equals(myStr1)) {

You can wrap the null and equals checking up in a small method -

package com....;

public class ObjectUtils {
public static boolean eq(Object a, Object b) {
return a==b || (a != null && a.equals(b));
}
}
.....
import static com.....ObjectUtils.eq;
....
if (eq(myStr1, myStr2)) {

Tom Hawtin
 
S

steve

If I have declared 2 strings as follows:
private String myStr1 = "";
private String myStr2 = "";
and somewhere in the application they may or may not get assigned
values. When I do
if (myStr1.equals(myStr2))
....
I will get an exception if myStr1 is null. How do I test it without
using
if (myStr1 != null)
if (myStr1.equals(myStr2))
....
?
I have a lot of string comparisons like the above, and if I have to
test one by one like that, it's a lot of code!
Thanks.

code it like this

if ( myStr1 !=null && myStr1.equals(myStr2)){}

java normally evaluates if statements from left to right , therefore if the
first action fails the rest of the if statement is NOT evaluated.
 
J

Jean-Marie Gaillourdet

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hi,
code it like this

if ( myStr1 !=null && myStr1.equals(myStr2)){}

java normally evaluates if statements from left to right , therefore if the
first action fails the rest of the if statement is NOT evaluated.

Your observation is right, but your explanation not exactly right. If
statement conditions have the same evalution order than any other
expression. But && is defined to do short circuit evalution, which means
that it first checks the left subexpression and only if it is still
possible to evaluate the whole expression to true, the right
subexpression is evaluated. The same applies to ||. Just to be clear in
my point: I want to remark, that this is not a property of the if but a
property of the &&.

Regards,
Jean-Marie
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.1 (GNU/Linux)
Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org

iD8DBQFEF9ynNIUNP/I5YOgRAngSAJ9Sgvd7goN3n14LfnoMkxeRoXylowCePRIe
HXg1KYEq6RKYgOlHe01H3i8=
=EwBd
-----END PGP SIGNATURE-----
 
T

tom fredriksen

Jean-Marie Gaillourdet said:
Your observation is right, but your explanation not exactly right. If
statement conditions have the same evalution order than any other
expression. But && is defined to do short circuit evalution, which means
that it first checks the left subexpression and only if it is still
possible to evaluate the whole expression to true, the right
subexpression is evaluated. The same applies to ||. Just to be clear in
my point: I want to remark, that this is not a property of the if but a
property of the &&.

The difference being that a || expression will short circuit if it meets
a true value expression while a && expression will short circuit if it
meets a false value expression.

/tom
 
S

steve

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hi,


Your observation is right, but your explanation not exactly right. If
statement conditions have the same evalution order than any other
expression. But && is defined to do short circuit evalution, which means
that it first checks the left subexpression and only if it is still
possible to evaluate the whole expression to true, the right
subexpression is evaluated. The same applies to ||. Just to be clear in
my point: I want to remark, that this is not a property of the if but a
property of the &&.

Regards,
Jean-Marie
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.1 (GNU/Linux)
Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org

iD8DBQFEF9ynNIUNP/I5YOgRAngSAJ9Sgvd7goN3n14LfnoMkxeRoXylowCePRIe
HXg1KYEq6RKYgOlHe01H3i8=
=EwBd
-----END PGP SIGNATURE-----

sorry i was sloppy.

I should have said:

Evaluations are run from left to right and once the evaluation reaches a
definitive condition that cannot be altered by any other evaluation in the if
statement, the remaining evaluations are skipped.

It IS a function of the if statement.
it is not actually strictly a property of &&, I can think of some bitwise
operations (&)

Steve
 
C

Chris Uppal

steve said:
I should have said:

Evaluations are run from left to right and once the evaluation reaches a
definitive condition that cannot be altered by any other evaluation in
the if statement, the remaining evaluations are skipped.

It IS a function of the if statement.
it is not actually strictly a property of &&, I can think of some
bitwise operations (&)

No, this is not true. The "if" is completely irrelevant. E.g in:

boolean b = aTest() && anotherTest();

anotherTest() will only be executed if aTest() returns true. That is a defined
property of the && operator. Similarly the || and ?: operators are defined to
do short-circuited evaluation.

In contrast the bitwise/logical operations, & and |, do /not/ do
short-circuited evaluation, not even when applied to boolean arguments, and not
even in the condition of an "if" statement.

See the JLS sections 15.23, 15.24, and 15.25, for the spec for &&, ||, and :?
respectively. See section 15.22 for the spec for & and |.

-- chris
 
S

Stefan Ram

Chris Uppal said:
No, this is not true.

To avoid this misinterpretation (which is well-known to me),
in my classes, I teach »&&« strictly separated from »if« and
from »?:«. (In fact, I do not use »if« at all in my course as
of now.)

It is regrettable that courses often show »&&« only in the
context of »if«, so that beginners are lead to assume that
»&&« can only occur in this context.
 
L

Lasse Reichstein Nielsen

Roedy Green said:
Java inherits a complex set of precedence rules from C++ where most
evaluations work left to right but some right to left e.g. casts.

Casts aren't really binary operations on expressions, since only one
operand can be an expression. The other must be a type literal.
Associativity only makes sense for infix (and therefore binary or
higher-ary) operators of the same arity. Unary operators are either
prefix or postfix, but they have no associativity (only precendence).

Associativity is a disambiguation device for making parsing of
expressions unambiguous. The expression 4-3-2 could be ambiguously
parsed as either (4-3)-2 or 4-(3-2), so Java specifies that
associativity is left-to-right for infox operators with that
precendence (i.e., "+" and "-").

In Java, the only ternary infix operator (?:) has a syntax that makes
associativity irrelevant, since parsing is always unambiguous. This
can be compared to the if/else statement where the "else" can be
omitted, so a statement like if (a) if (b) x=2; else x=4; needs
disambiguation in the syntax to decide which "if" the "else" belongs
to (it's the inner if).

A better example of right-to-left evaluation order would be
assignments.

(I can see your table have two rows with precedence 1. I think it would
be just as correct to move the postfix operators to the top and give
them precedence 0.)
/L
 
J

Jaakko Kangasharju

Roedy Green said:
Java inherits a complex set of precedence rules from C++ where most
evaluations work left to right but some right to left e.g. casts.

No, Java order of evaluation is always left to right (JLS 15.7).
Order of evaluation has nothing to do with precedence and
associativity.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,764
Messages
2,569,567
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top