Is it possible to convert null to int?

I know that when I read the answer to this, I will see that I missed something; it was under my eyes. But the last 30 minutes I tried to figure it out myself without a result.

So, I wrote a program in Java 6 and discovered some (for me) strange functions. To try to isolate it, I made two small examples. First I tried the following method:

private static int foo() { return null; } 

and the compiler abandoned it: Type of mismatch: cannot be converted from null to int.

This is good with me, and he respects the semantics of Java that I am familiar with. Then I tried the following:

 private static Integer foo(int x) { if (x < 0) { return null; } else { return new Integer(x); } } private static int bar(int x) { Integer y = foo(x); return y == null ? null : y.intValue(); } private static void runTest() { for (int index = 2; index > -2; index--) { System.out.println("bar(" + index + ") = " + bar(index)); } } 

This is a compilation without errors! But, in my opinion, there should be a type conversion error in the string

  return y == null ? null : y.intValue(); 

If I run the program, I get the following output:

 bar(2) = 2 bar(1) = 1 bar(0) = 0 Exception in thread "main" java.lang.NullPointerException at Test.bar(Test.java:23) at Test.runTest(Test.java:30) at Test.main(Test.java:36) 

Can you explain this behavior?

Update

Thanks so much for the many clarifying answers. I was a little worried because this example did not fit my intuition. One thing that bothered me was that null was converted to int, and I was wondering what the result would be: 0 like in C ++? That would be very strange. It is good that conversion is not possible at runtime (null pointer exception).

+43
java
Jul 05 2018-11-11T00:
source share
7 answers

Look at the line:

 return y == null ? null : y.intValue(); 

In the operator ? : ? : both sides : must be of the same type. In this case, Java will be of type Integer . Integer may be null , so the left side is fine. The expression y.intValue() is of type int , but Java will automatically put it in the Integer value (note that you could just write y , which would save you this autobox).

Now the result should be unpacked to int again, since the return type of the int method. If you remove Integer null , you will get a NullPointerException .

Note: Does paragraph 15.25 of the Java language specification explain the exact type conversion rules for a conditional statement ? : ? : .

+50
Jul 05 2018-11-21T00:
source share

Guava has a pretty elegant solution for this using MoreObjects.firstNonNull :

 Integer someNullInt = null; int myInt = MoreObjects.firstNonNull(someNullInt, 0); 
+12
Feb 24 '15 at 15:47
source share

The return type is inferred here by Java. This is problem..

http://java.sun.com/docs/books/jls/third_edition/html/expressions.html#15.25

Here is the real problem -

If one of the second and third operands is of type zero, and the type of the other is a reference type, then the conditional expression type is a reference type.

Thus, basically the compiler displays the return type of the conditional expression as a whole, and therefore it allows you to successfully compile.

EDIT: see the rules in the comments

+6
Jul 05 2018-11-21T00:
source share

This illustrates the problematic difference between how a person reads code and a compiler reads code.

When you see a triple expression, you can mentally divide it into two parts in the style of the if / else expression:

 if (y == null) return null; else return y.intValue(); 

You can see that this is unacceptable as it leads to a possible branch where the method defined to return int actually returns null (illegal!).

What the compiler sees is an expression that must have a type. He notes that the triple operation includes a null on one side and a int on the other; due to the behavior of autoboxing Java, then there is a β€œbetter guess” (my term, not Java) regarding what type of expression: Integer (this is true: this is the only type that can be legally null or in an int box).

Since the method should return int , this is different from the perspective of the compiler: the return expression evaluates to Integer , which can be automatically unpacked.

+3
Jul 05 '11 at 21:30
source share

Just in case, if you are not using Guava in your project, but are already using Apache Commons, you can use Apache Lang3 with its ObjectUtils class.

Usage is basically the same as Guava:

 Integer number = null; int notNull = ObjectUtils.firstNonNull(number, 0); 

Note that this method is faster in the Guava library than in Apache. Here is a short comparison that I just made on my laptop (Core i7-7500U 2.7 GHz), Oracle Java 8, several starts, JVM preheating, the results are averaged:

 ╔══════════════╦══════╦══════╦════════╦══════╗ β•‘ Library/Runs β•‘ 1000 β•‘ 1mln β•‘ 100mln β•‘ 1bln β•‘ ╠══════════════╬══════╬══════╬════════╬══════╣ β•‘ Apache β•‘ 1 β•‘ 30 β•‘ 782 β•‘ 9981 β•‘ β•‘ Guava β•‘ 1 β•‘ 22 β•‘ 120 β•‘ 828 β•‘ β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•©β•β•β•β•β•β•β•©β•β•β•β•β•β•β•©β•β•β•β•β•β•β•β•β•©β•β•β•β•β•β•β• 

Results are in milliseconds. I don’t think you often need to run this method billions of times, but it’s always useful to compare performance

+3
Feb 25 '17 at 21:18
source share

The problem with autounboxing null values ​​can be very annoying. In your example, this is a combination of type inference of a ternary operator, output and autounboxing (with JLS you should consult why it behaves like this)

But in general, you should try to avoid using wrapper types. Use int instead of Integer . If you need a special value meaning "no result", you can use Integer.MAX_VALUE , for example.

+1
Jul 05 2018-11-11T00:
source share

this one compiles

 private static int foo() { return (Integer)null; } 
+1
Jul 05 2018-11-21T00:
source share



All Articles