JDK-7133658 : Make Number classes' parsing behavior consistent
  • Type: Enhancement
  • Component: core-libs
  • Sub-Component: java.lang
  • Affected Version: 7
  • Priority: P4
  • Status: Closed
  • Resolution: Duplicate
  • OS: windows_7
  • CPU: x86
  • Submitted: 2012-01-26
  • Updated: 2012-03-20
  • Resolved: 2012-01-27
Related Reports
Duplicate :  
Description
A DESCRIPTION OF THE REQUEST :
The various primitive wrapper classes' parseX() methods have inconsistent behavior when a null param is supplied.

These throw NumberFormatException
Byte.parseByte(null)
Short.parseShort(null)
Integer.parseInteger(null)
Long.parseLong(null)

These throw NullPointerException
Float.parseFloat(null)
Double.parseDouble(null)

This behavior was present in JDK 6, though the javadoc was (and the online version still is) incorrect.

BigDecimal and BigInteger throw NullPointerException when constructed with a null String, though their (JDK 7) javadoc indicates they too should throw NumberFormatException.

JUSTIFICATION :
These classes all descend from Number. Producing an instance from a String should have consistent behavior across the hierarchy. We expect parsing Numbers from Strings to fail in a consistent manner.

Historical javadoc actually documented these as conisistent, though their implementation was not.

I would expect the single String constructors of BigDecimal and BigInteger to perform this was as well. Currently they throw NullPointerExcecption, despite the current Javadoc declaring they should throw NumberFormatException.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Supplying null to the parseX() method for Primitive Wrapper descending from Number or constructing BigDecimal or BigInteger with a null String shoudl throw a NumberFormatException.

Alternatively, they should thow NullPointerException; regardless the behvior should be consistent across the classes.
ACTUAL -
Some classes throw NullPointerException, some throw NumberFormatException. See Description for details.

---------- BEGIN SOURCE ----------
This code show all cases:
	public static void main(String[] args) {
		
		System.out.println(System.getProperties().toString());

		System.out.println("\nRunning Boolean.parseBoolean(null)");
		
		try {
			System.out.println(Boolean.parseBoolean(null));
		} catch (NumberFormatException nfe){
			System.out.println("Caught NumberFormatException");
		} catch (NullPointerException npe){
			System.out.println("Caught NullPointerException");
		}
		
		System.out.println("\nRunning Byte.parseByte(null)");
		
		try {
			Byte.parseByte(null);
		} catch (NumberFormatException nfe){
			System.out.println("Caught NumberFormatException");
		} catch (NullPointerException npe){
			System.out.println("Caught NullPointerException");
		}
		
		System.out.println("\nRunning Short.parseShort(null)");
		
		try {
			Short.parseShort(null);
		} catch (NumberFormatException nfe){
			System.out.println("Caught NumberFormatException");
		} catch (NullPointerException npe){
			System.out.println("Caught NullPointerException");
		}
		
		System.out.println("\nRunning Integer.parseInteger(null)");
		
		try {
			Long.parseLong(null);
		} catch (NumberFormatException nfe){
			System.out.println("Caught NumberFormatException");
		} catch (NullPointerException npe){
			System.out.println("Caught NullPointerException");
		}
		
		System.out.println("\nRunning Long.parseLong(null)");
		
		try {
			Long.parseLong(null);
		} catch (NumberFormatException nfe){
			System.out.println("Caught NumberFormatException");
		} catch (NullPointerException npe){
			System.out.println("Caught NullPointerException");
		}
		
		System.out.println("\nRunning Float.parseFloat(null)");
		
		try {
			Float.parseFloat(null);
		} catch (NumberFormatException nfe){
			System.out.println("Caught NumberFormatException");
		} catch (NullPointerException npe){
			System.out.println("Caught NullPointerException");
		}

		System.out.println("\nRunning Double.parseDouble(null)");
		
		try {
			Double.parseDouble(null);
		} catch (NumberFormatException nfe){
			System.out.println("Caught NumberFormatException");
		} catch (NullPointerException npe){
			System.out.println("Caught NullPointerException");
		}

		System.out.println("\nRunning new BigInteger((String)null)");
		
		try {
			String s = null;
			new BigInteger(s);
		} catch (NumberFormatException nfe){
			System.out.println("Caught NumberFormatException");
		} catch (NullPointerException npe){
			System.out.println("Caught NullPointerException");
		}

		System.out.println("\nRunning new BigDecimal(null)");
		
		try {
			String s = null;
			new BigDecimal(s);
		} catch (NumberFormatException nfe){
			System.out.println("Caught NumberFormatException");
		} catch (NullPointerException npe){
			System.out.println("Caught NullPointerException");
		}

	}

---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
Write catch clauses for both. Prevalidate parameters.

Comments
EVALUATION While the behavior of the parsing methods is not consistent across classes, it is certainly documented. The javadoc of Float.parseFloat includes Throws: NullPointerException - if the string is null as does Double.parseDouble. Closing as duplicate of 4787924.
27-01-2012