I have the following code:
public class Main {
public static void main(String[] args) {
String pattern = ".00"; // a) => |.46|
// String pattern = ".##"; // b) => |.46|
// String pattern = ".0#"; // c) => |.46|
// String pattern = "#.00"; // d) => |.46|
// String pattern = "#.0#"; // e) => |.46|
// String pattern = "#.##"; // f) => |0.46|
// String pattern = ".#0"; // g) => IllegalArgumentException: Malformed pattern ".#0"
double value = 0.456;
DecimalFormat df = (DecimalFormat) NumberFormat.getNumberInstance(Locale.US);
df.applyPattern(pattern);
String output = df.format(value);
System.out.printf("|%s|", output);
}
}
Could someone explain that why in f) the zero before decimal point still displays while d) and e) don't even though they are all have a '#' before decimal point in the pattern? Also, what could be the reason for the exception in g) as it seems to me a valid pattern?
In case "f", the zero shows up because Java prints a
0if it's not guaranteed that there is a fraction part to print. The below code is taken from JDK 17 source code forDecimalFormat. Because you have all#after the decimal point,minFraDigitsis0so it can't assume that a fraction is present. It apparently doesn't see that there is a fraction part to print yet. It guards against printing nothing if the value is zero.The case "g" format is an invalid format. You can't have a
0further from the decimal point than a#. It's enforced in the parsing grammar in theDecimalFormatjavadocs. For the Fraction part, the zeros must come first if they exist, followed by optional#s.Another part of the grammar similar to this enforces that before the decimal point, any
#s must be before any0s, the reverse of after the decimal point.