Your code makes use of two different additive operators. The first three lines use string concatenation, whereas the last one uses numeric addition.
String concatenation is well-defined to turn null into "null":
- If the reference is
null, it is converted to the string"null"(four ASCII charactersn,u,l,l).
Hence there is no NPE.
Adding two Integer objects together requires them to be unboxed. This results in the null reference being dereferenced, which leads to the NPE:
Answer from NPE on Stack Overflow
- If
ris null, unboxing conversion throws aNullPointerException
Your code makes use of two different additive operators. The first three lines use string concatenation, whereas the last one uses numeric addition.
String concatenation is well-defined to turn null into "null":
- If the reference is
null, it is converted to the string"null"(four ASCII charactersn,u,l,l).
Hence there is no NPE.
Adding two Integer objects together requires them to be unboxed. This results in the null reference being dereferenced, which leads to the NPE:
- If
ris null, unboxing conversion throws aNullPointerException
Notice that first three + operator usages involve string concatenation. Only the last one is the actual numeric sum. When string concatenation is involved (where s variable is involved), Java compiler uses some clever trick to improve performance. It replaces + operator with StringBuilder. For example your first line is translated to:
StringBuilder tmp = new StringBuilder();
tmp.append(s);
tmp.append(i);
System.out.println(tmp);
StringBuilder is null-friendly so no matter what you pass as an argument, it nicely replaces it with "null" string.
The situation is different in the last line. There you reference two Integer objects. The only that the JVM can do here is to unbox them (i.intValue()) and do the actual computation. Unboxing of null causes NullPointerException.
NullPointerException possibility in Integer.toString(arg) method in java - Stack Overflow
java - Why Integer doesn't solve null String - Stack Overflow
java - Converting a String to int. Set the int to 0 if String is null - Stack Overflow
java - Convert null object to String - Stack Overflow
You cannot cast from String to Integer. However, if you are trying to convert string into integer and if you have to provide an implementation for handling null Strings, take a look at this code snippet:
String str = "...";
// suppose str becomes null after some operation(s).
int number = 0;
try
{
if(str != null)
number = Integer.parseInt(str);
}
catch (NumberFormatException e)
{
number = 0;
}
If you're using apache commons, there is an helper method that does the trick:
NumberUtils.createInteger(myString)
As said in the documentation:
"convert a String to a Integer, handling hex and octal notations; returns null if the string is null; throws NumberFormatException if the value cannot be converted.
Integer.toString(args) may give an NullPointerException unlike String.valueOf(args).
Integer i = null;
Integer.toString(i); // Null pointer exception!!
String.valueOf(i); // No exception
i.toString(); // Again, Null pointer exception!!
See my experiment here : http://rextester.com/YRGGY86170
Technically yes, due to unboxing. Although I'm not sure if that is what you meant:
public class Test {
public static void main(String[] args) {
Integer i = null;
System.out.println(Integer.toString(i)); // NullPointerException
}
}
null is not a valid representation of integer number. Integer.parseInt() requires that the string be parsed is a vaild representation of integer number.
Integer.parseInt()
public static int parseInt(String s, int radix)
440 throws NumberFormatException
441 {
442 if (s == null) {
443 throw new NumberFormatException("null");
444 }
Integer.valueOf(str)] // which inviokes Integer.parseInt(Str) to return an Integer instance.
public static Integer valueOf(String s) throws NumberFormatException
569 {
570 return new Integer(parseInt(s, 10));
571 }
The folks at Sun who implemented Integer (a long time ago :) ) probably were not thinking of databases when they wrote that method. Except when dealing with database data, or rare cases where you are trying to explicitly represent "unknown" with null, null is usually a sign of something gone terribly wrong. In general, it's a good idea to raise an exception as soon as there is a problem. (a Fail fast design)
If you have ever spent time hunting down a segmentation fault in C that is due to a string value longer than the memory you supplied for it (which then overwrote some program code or other data) you will have a very good appreciation of how bad it is to not fail when something has gone wrong.
Since the time of Java 1.0, interaction with databases in java has become extremely common so you might be right to suggest that there should be a method to handle this. Integer is a final class so if you build your own Integer like class you will loose autoboxing, so this probably does require a change to the language by oracle.
Basically, what you observed is the way it is for now, and someone will have to pay you to code around it :)
Simply use the built-in method JSONObject#getInt(String), it will automatically convert the value to an int by calling behind the scene Integer.parseInt(String) if it is a String or by calling Number#intValue() if it is a Number. To avoid an exception when your key is not available, simply check first if your JSONObject instance has your key using JSONObject#has(String), this is enough to be safe because a key cannot have a null value, either it exists with a non null value or it doesn't exist.
JSONObject jObj = jsonarray.getJSONObject(i);
int block_id = jObj.has("block_id") ? jObj.getInt("block_id") : 0;
Instead of writing your own function use the inbuild construction of try-catch. Your problem is, that jsonarray or jsonarray.getJSONObject(i) or the value itself is a null and you call a method on null reference. Try the following:
int block_id = 0; //this set's the block_id to 0 as a default.
try {
block_id = Integer.parseInt(jsonarray.getJSONObject(i).getString("block_id")); //this will set block_id to the String value, but if it's not convertable, will leave it 0.
} catch (Exception e) {};
In Java Exceptions are used for marking unexpected situations. For example parsing non-numeric String to a number (NumberFormatException) or calling a method on a null reference (NullPointerException). You can catch them in many ways.
try{
//some code
} catch (NumberFormatException e1) {
e.printStackTrace() //very important - handles the Exception but prints the information!
} catch (NullPointerException e2) {
e.printStackTrace();
}
or using the fact, that they all extend Exception:
try {
//somecode
} catch (Exception e) {
e.printStackTrace;
};
or since Java 7:
try {
//somecode
} catch (NullPointerException | NumberFormatException e) {
e.printStackTrace;
};
Note
As I believe, that you'll read the answer carefully, please have in mind, that on StackOverflow we require the Minimal, Complete, and Verifiable example which include the StackTrace of your exception. In your case it probably starts with the following:
Exception in thread "main" java.lang.NullPointerException
Then, debugging is much easier. Without it, it's just guessing.
Edit: According to the accepted answer
The accepted answer is good and will work as long, as the value stored with key: block_id will be numeric. In case it's not numeric, your application will crash.
Instead of:
JSONObject jObj = jsonarray.getJSONObject(i);
int block_id = jObj.has("block_id") ? jObj.getInt("block_id") : 0;
One should use:
int block_id;
try{
JSONObject jObj = jsonarray.getJSONObject(i);
block_id = jObj.has("block_id") ? jObj.getInt("block_id") : 0;
} catch (JSONException | NullPointerException e) {
e.printStackTrace();
}
Instead of catching the exception or putting conditions, use
String.valueOf(result.getPropertyAsString(0));
It will call toString() method of the argument and will convert it to String and if result.getPropertyAsString(0) is null, then it will change it to "null".
Although it's not a good practice, you can concatenate the null value with "" to make it a String.
For example:
String str=null;
System.out.println((str+"").length()); /// prints 4
The static valueOf method in the String class will do the null check and return "null" if the object is null:
String stringRepresentation = String.valueOf(o);
Try Objects.toString(Object o, String nullDefault)
Example:
import java.util.Objects;
Object o1 = null;
Object o2 = "aString";
String s;
s = Objects.toString(o1, "isNull"); // returns "isNull"
s = Objects.toString(o2, "isNull"); // returns "aString"
I am sure you are over-complicating the problem, it is a real simple thing to do. Check the code below:
Integer i = null;
System.out.println(i == null ?"":i);
Use Integer wrapper class instead of primitive
Integer myInt= null;
For object references you can set null.But you cannot to primitives.
You could try it like this using the ternary operator.
System.out.println(a == null ? "" : a);
Alernatively, you can use the Commons Lang3 function defaultString() as suggested by chrylis,
System.out.println(StringUtils.defaultString(a));
I would factor out a utility method that captures the intention, which improves readability and allows easy reuse:
public static String blankIfNull(String s) {
return s == null ? "" : s;
}
Then use that when needed:
System.out.println(blankIfNull(a));
Though it works, i + "" is kind of hack to convert int to String. The + operator on string never designed to use that way. Always use String.valueOf()
Use whatever method is more readable. String.valueOf(i) or Integer.toString(i) make your intent much clearer than i + "".