Understanding the difference between null and '\u000' in Java - java

I read in a book (Thinking in Java by Bruce Eckel, 4th edition, page 47) that null is equal to '\u000'. And then I was wondering what exactly does '\u000' really mean.
As per my understanding null was nothing or absence of anything. And '\u000' comes in contradiction with this definition.
Can anyone clarify this issue about null and '\u000'?

The language specification is where null is defined, and it says
There is also a special null type, the type of the expression null, which has no name. Because the null type has no name, it is impossible to declare a variable of the null type or to cast to the null type. The null reference is the only possible value of an expression of null type. The null reference can always be cast to any reference type. In practice, the programmer can ignore the null type and just pretend that null is merely a special literal that can be of any reference type. --Link to documentation (Section 4.1)
and
The null type has one value, the null reference, represented by the literal null, which is formed from ASCII characters. A null literal is always of the null type. --Link to documentation (Section 2.3)
Rather a circular sounding definition, but the value of null is the null reference itself - just another pointer. The value of the null reference isn't really relevant and is presumably up to the implementor, but zero or some other value that can't be confused with another object address is likely.
Confusion may be caused here because there is a character value called the null character with value \u0000. This is the default value for type char.

\u000 would be the unicode representation of a character with ASCII code 0, but has nothing to do with null as used by Java.

'\u0000'
decimal equivalent is 00
Char equivalent is NUL.
From Character in Javadoc: http://docs.oracle.com/javase/1.4.2/docs/api/java/lang/Character.html
static char MIN_VALUE
The constant value of this field is the smallest value of type char, '\u0000'.
This is the unicode value, that in CHAR is equivalent to NULL, ie it is the NULL CHARACTER, rather than being the literal NULL.

null is a literal and you can see the specification which says
in practice you can simply pretend that it's "merely a special literal that can be of any reference type".
as #assylias said what you read was surely not out of java :)

Related

Why is Java evaluating the wrong side of ternary operation?

I might miss some simple explanation, but the following line throws a NullPointerException:
Long sum = true
?
fiscalDocumentUtil.getFullValue(fiscalDocument.getInvoice())
:
(long) fiscalDocument.getReceipt().getAmount();
While
Long sum = true
?
fiscalDocumentUtil.getFullValue(fiscalDocument.getInvoice())
:
null
does not. I would also like to mention that
fiscalDocumentUtil.getFullValue(fiscalDocument.getInvoice())
does not throw an exception on its own, while
(long) fiscalDocument.getReceipt().getAmount()
does.
Is the second side evaluated? Or am I butchering something?
EDIT
Some additional info, asked in the comments:
fiscalDocumentUtil.getFullValue(fiscalDocument.getInvoice()) returns null.
The return type of fiscalDocumentUtil.getFullValue(fiscalDocument.getInvoice()) is Long.
The return type of fiscalDocument.getReceipt().getAmount() is Integer.
If I emit the explicit (long) conversion, the behavior is the same.
Edit 2
A minimal reproducible example: Long val =true ? (Long) null: Integer.valueOf(1);. This was partially suggested by the answer of MC Emperor and partially suggested by comments. Of course, this example already somewhat answers the question, since the second expression does not need to throw an exception, as it turns out.
If foo has type Long and bar has type long, then true ? foo : bar has type long, and is equivalent to true ? foo.longValue() : bar. As the Java Language Specification puts it:
If one of the second and third operands is of primitive type T, and the type of the other is the result of applying boxing conversion (§5.1.7) to T, then the type of the conditional expression is T.
(In your case, T is long, and "the result of applying boxing conversion (§5.1.7) to T" is Long.)
The fact that you try to put the result in a Long variable doesn't change that fact; it just gives you the equivalent of Long.valueOf(true ? foo.longValue() : bar), with unboxing followed by boxing.
In your case, foo == null, so the unboxing throws a NullPointerException, so the boxing never happens.
Well, Java only evaluates the left expression, as the condition is true.
You said that fiscalDocumentUtil.getFullValue(fiscalDocument.getInvoice()) in itself does not throw an NullPointerException.
The only thing I can think of, is that fiscalDocumentUtil.getFullValue(fiscalDocument.getInvoice()) returns null. Reproducible with:
Long sum = true ? null : (long) 23L;
Because one of the operands is a primitive, the other one is subject to boxing conversion, in this case, unboxed to long.

Why does Java cast the null reference to String "null"? [duplicate]

This question already has answers here:
Why does null reference print as "null"
(3 answers)
Closed 6 years ago.
In Java, if I write:
System.out.println((String) null);, I get "null".
This seems weird. Does anyone know why the designers chose this approach? It seems to me that this is a case of "creating something out of nothing". I've read the JLS entry on cast operators, and it says:
The type of a cast expression is the result of applying capture conversion (§5.1.10) to the type whose name appears within the parentheses.
The result of a cast expression is not a variable, but a value, even if the result of the operand expression is a variable.
Jumping to the entry on capture conversion, I see capture conversion defined for generic types, but the entry adds:
Capture conversion on any type other than a parameterized type (§4.5) acts as an identity conversion (§5.1.1).
Okay! On to the entry on identity conversion and there's this:
A conversion from a type to that same type is permitted for any type.
In this case, the type is String but the thing to be converted is null and that left me confused. However, it turns out that Java is actually using String conversion for (String) null. The JLS entry on String conversion says:
Any type may be converted to type String by string conversion...
If the reference is null, it is converted to the string "null" (four ASCII characters n, u, l, l).
One problem that this raises is this:
HashMap map = new HashMap();
System.out.println((String)map.get("something"));
The program prints "null". How do I know whether it was that because entry was null versus the String in the HashMap has value "null" (four ASCII characters 'n', 'u', 'l', 'l')? Now I know someone will say that Java discourages the use of raw types, and that the type HashMap should be parameterized but is that the solution?
You are overthinking this. Java is not casting (the value) null to (the string) "null". The correct answer is that this is merely an explicit behavior of the PrintStream.println(String) method:
Prints a String and then terminate the line. This method behaves as though it invokes print(String) and then println().
Next we consult what PrintStream.print(String) has to say:
Prints a string. If the argument is null then the string "null" is printed. Otherwise, the string's characters are converted into bytes according to the platform's default character encoding, and these bytes are written in exactly the manner of the write(int) method.
(Remember, the type of System.out is PrintStream.)
HashMap map = new HashMap();
System.out.println((String)map.get("something"));
The program prints "null". How do I know whether it was that because
entry was null versus the String in the HashMap has value "null"
(four ASCII characters 'n', 'u', 'l', 'l')?
There's still a difference between null and "null", you just can't see that when you print them out with System.out.println. They're different values, and they do compare differently:
HashMap map = new HashMap();
map.put("foo", "null");
String something = (String) map.get("something");
String foo = (String) map.get("foo");
System.out.println(something == null); // true
System.out.println(foo == null); // false
System.out.println("null".equals(something)); // false
System.out.println("null".equals(foo)); // true
It does nothing to do with casting, but with printing: If you cast a null to String, it is still a null:
String s=(String)null;
if (s==null)
{
System.out.println("It is still a null");
}
else
{
throw new RuntimeException("This won't happen");
}
So you shouldn't have any difficulties to check if a value returned by a Map, Collection, or whatever API is null or not, simply performing a direct comparation by program.
In the other hand, never trust the result printed directly to the standard output by a PrintStream (as System.out). See the documentation of PrintStream.print(String).
Moreover: The same ambiguity happens when printing a number or a boolean: If you see on the standard output "123", is it a number value or a string value? I insist: To check values, never trust the appearance of a string printed out to a PrintStream.

What does is mean by null pointing to nothing and why use null at all?

There are a lot of questions about null and in java.
What I am failing to grasp is what people mean by null is pointing to nothing or why to use null at all.
I can't understand the difference between
String thing = null;
and
String thing = "";
This question has detailed answers What is null in Java?, but I just can't wrap my head around it.
What am I missing?
languages I've studied (no expert)
Python, vb (vb.net), web programming (html, css, php, bit of js), sql
I should add, it is this answer https://stackoverflow.com/a/19697058/2776866 which prompted me to write this.
String str = null;
means a String reference, named str, not pointing to anything
String str = "";
means a String reference, named str, pointing to an actual String instance. And for that String instance, it is a zero-length String, but it is still an actual object.
Just a little update with some diagram which hopefully can help you visualize that:
assume I have
String nullStr = null;
String emptyStr = "";
String myStr = "ab";
What it conceptually is something look like:
// String nullStr = null;
nullStr ----------> X pointing to nothing
// String emptyStr = "";
+------------------+
emptyStr ---------> | String |
+------------------+
| length = 0 |
| content = [] |
+------------------+
// String myStr = "ab";
+------------------+
myStr ------------> | String |
+------------------+
| length = 2 |
| content = [ab] |
+------------------+
(of course the internal structure of the String object is not the real thing in Java, it is just for giving you an idea)
More edit for the rationale behind NULL:
In fact in some language they do not provide concept of NULL. Anyway, in Java (or similar language), Null means semantically different from "empty" object. Use String as an example, I may have a People class with a String preferedTitle attribute. A Null preferedTitle means there is NO preferred title for that people (so that we need to derive and show the title for it, maybe), while a preferedTitle being an empty string means there IS a preferred title, and that's showing nothing.
Btw, although a bit off topic: concept of Null is seen as problematic for some people (because all those extra handling it need etc). Hence some languages (e.g. Haskell) are using some other ways to handle the situation where we used to use Null.
String str is a reference to an object. That is, it's not an actual object, but a variable which can contain the address of an object. When you assign a value to str you are changing the address stored within and changing which object it addresses.
null is reference value which points to no object. It's about as close to nothing as you can get. If you assign null to a String reference (String str = null;), you cannot then invoke any method of String using that reference -- all attempts will result in NullPointerException.
"" is a character String which contains no characters -- zero length. It is still an object, though, and if you assign its address to your String reference variable (String str = "";) you can then take its length, compare it to another String, extract its hashCode, etc.
Java doesn't really expose pointers, instead it deals with references.
When you say
String thing = null;
You are saying that there is a reference (of type string) called thing, which isn't referencing anything.
When you say
String thing = ""
This is shorthand for,
String thing = new String("");
Now you have an actual object initialized and ready to be used. You told the compiler to create a string and now your "thing" references the new string.
If you want to know the length of your initialized string, you can go;
thing.length
Which is zero. The string exists, but is zero length.
Trying string.length on the null version causes a NullReferenceException, which is the compiler saying
"I tried to find out about the length of your string, but I couldn't find it!"
Practically speaking, null means "not available for calling methods". If an object is allowed to be null, you must always check it for null before calling method on it.
An attempt to call any method on a null object is unconditionally an error. In nearly all cases it's a programming error, too, because you are supposed to either
Ensure that a variable is always non-null, or
Check a variable that could legally be null before calling methods on it.
On the other hand, an empty object lets you call methods. For example, you can find the length of an empty string - it is zero. You could also iterate a string, pass it to methods that expect non-null strings, and so on.
To visualize this, consider a Boolean object instead of a String. Unlike the primitive boolean that has only two states, namely true ("yes") and false ("no"), the Boolean object has three states:
Yes
No
Don't know
This third "don't know" state corresponds to null. It's neither true nor false state. Your program can use this third state to its advantage - for example, you can use comparison to null to see if a value has been set, or set a value to null to "unset" its value.
In Java null and an empty String are two different things.
If an String is null then you can not access its methods as it will throw a NullPointerException, however if a String is "" then the String object is valid and you can access its methods.
For example
String a = null;
String b = "";
System.out.println (a.length()); // No Good
System.out.println (b.length()); // Prints 0
Let's compare this to Python. In Python, the equivalent to null is None.
>>> test = ""
>>> test1 = None
This is setting an empty string and a "null" string.
>>> test
''
>>> test1
None
In Python we can test nullity using is
>>> test is None
False
>>> test1 is None
True
We can test for empty strings using ==
>>> test == ""
True
>>> test1 == ""
False
null (like None) is the absence of a value.
Conceptually null is a special value which means that the variable points to an invalid object, so it doesn't refer to anything valid in the sense that you can't access its content (variables or methods).
You can see it as a sort of special condition which has been added to languages because it was useful to be able to have pointers that refer to nothing. But there is some discordance here, in fact some languages prevent the necessity of a null value by forcing you to have just inizialized (meaningful) values.
There is difference in your example, "" is a valid object: it's an empty string while null is not a valid object.
Although many object-oriented frameworks implement references with pointers, it is better to think of references not as "pointing to" objects, but rather as "identifying" them [personally, I like the term "object identifier" to describe references, since the term "reference" is somewhat overloaded in different contexts]. Although object identifiers are not human readable, one can imagine the system as giving each object an associated number starting at 1, and each class-type variable as either having an object number or a zero written on it. Since class-type variables and array slots default to holding zero, and there will never be a zeroth object, there's no danger that the default-valued variable of an uninitialized variable or array slot will identify a valid object.
I prefer using the concept of containers/boxes to understand this concept
Let's start with this
String thing = "";
Imagine you have a container/box where you can store any value as long as you put the value between double quote marks "", if you decide to just put the double quotation mark without a value inside the box there is absolutely nothing wrong with that and any time you open your box you still see something inside (The double quotation mark )
Now This big man over here called null
String thing = null;
In simple terms look at null as being absolutely nothing
What does all this mean?
When you open the first box you see the double quotation ""
When you open the second box you see nothing (it's just an empty box)

Java ternary operator function overloading [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Java conditional operator ?: result type
NullPointerException through auto-boxing-behavior of Java ternary operator
Say I have two functions:
f(MyObject o) { ... }
f(int i) { ... }
And I call them like this:
f(someCondition ? 10 : null);
This compiles, but when I run it I get a null pointer exception (sorry I'm not sure on which condition). Some my questions are:
Why does it even compile? What is the type of foo ? 10 : null?
It clearly doesn't call the "correct" functions because that wouldn't cause an NPE. So which function is it calling? Does it do f((MyObject)10); or f((int)null)?
First of all, the problem doesn't have anything to do with the fact that you have overloaded versions of f. If you only have the version of f that takes an int, you get the same problem.
The thing is that both possible results of the ternary expression (before and after the :) must have the same type, because the whole expression condition ? expr1 : expr2 must have a single type. You can't have this expression evaluate to one type of condition is true, and another type if it is false.
So, the Java compiler is going to see if it can convert expr1 and expr2 to a single type. Note that int cannot be null (because it's a primitive type). However, 10 can be converted to Integer via autoboxing, and an Integer can also be null. So the type of the whole ternary expression is determined to be of type Integer. The result is either an Integer that contains the value 10 or an Integer that is null.
Step two is that you pass this Integer to f. Because f takes an int, it is auto-unboxed.
If you auto-unbox an Integer that is null, you get a NullPointerException - that's what happens here.
The type is Integer - an auto boxing is done to the 10.
f(int) is called, because it is the only accepted cast from Integer available (assuming no other overloads)
When you try to cast a null to an int - you get your NPE.
2. f(Object) is called since Integer is an Object. This is called reference type widening
(sorry for the initial mistake, read it as f(Object))

null comparison

This might sound like a real dumb question but please bear with me :)
so I have a if condition in my code like if ((msgBO.getEmpId().equals("") == false )) {
// do something
} My question is, if I make the above statement as msgBO.getEmpId().equals(null) == false
would it make any difference or this way I am trying to compare two different things?
Yes, there is a big difference between "" (the empty String) and null (no String at all).
Any Object reference can point to null. That represents 'no data' or 'nothing.' The empty string "" represents a String with no length.
An example of this is the following:
String one = null;
String two = "";
int oneLength = one.length();
int twoLength = two.length();
The first call to length will throw a NullPointerException. And the second will return 0.
These are different things. In particular, the test
msgBO.getEmpId.equals(null) == false
a.k.a.
!msgBO.getEmpId.equals(null)
is guaranteed to always succeed (at least, if the equals method involved is written according to the standard set of rules), since no object is ever allowed to compare equal to null:
For any non-null reference value x, x.equals(null) should return false.
(Documentation of equals)
So, in other word, if you already know, that msgBO.getEmpId != null, then you also know the outcome of the call to equals. And unless you know that msgBO.getEmpId != null, calling equals is a NullPointerException waiting to happen. So, one often sees:
msgBO.getEmpId != null && msgBO.getEmpId.equals("...stuff...")
or even
"...stuff...".equals(msgBO.getEmpId)
"" (an empty string) and null are not the same. .equals(null) on a String will never return true.
A null reference and String of length 0 are two completely different things in Java. Two other points:
getEmpId is either a getter method missing the braces for method invocation or a public field, which is generally frowned upon (and badly named in this case).
if getEmpId is/returns null, teh calling equals() on it will caus a NullPointerException - which is why you should reverse the comparison when comparing with literal strings: if("foo".equals(variable))
Comparing a boolean expression explicitly using == is ugly. Instead you can use negation: if(!msgBO.getEmpId.equals("")) or if(!msgBO.getEmpId != null)
They are different , what you want is
msgBO.getEmpId == null
for the other case
You are trying to compare two different things. It might still work, but one is checking for an empty string and one is checking if the variable is null.
Also a faster check to see if the string is empty is just to check
if (string.length == 0).
(You will get an exception, however, if the string is null so don't do this if null checking, unless you want to handle the null case with the caught exception).
It does make a difference.
msgBO.getEmpId.equals("") compares msgBO.getEmpId with an empty String
msgBO.getEmpId.equals(null) compares msgBO.getEmpId with a null value. This is wrong because it will throw NullPointerException if msgBO.getEmpId is null. If you want to check if the value is null you should use such a condition instead: msgBO.getEmpId == null.
What is correct in this situation depends on the type of a value returned by msgBO.getEmpId. If it isn't String then only comparing with null makes sense. If it is String both values may have sense and then it depends how you represent an empty value of msgBO.getEmpId. In this case if you use null for an empty value you should compare with null and if you use "" for an empty value you should compare with "".

Categories