I see that floats and doubles have suffixes in different cases. So what's the difference in suffix F and f for floats, D and d for doubles ? Any history of this behavior ?
Also question about type constructor for example for float type (same behavior for double): Why can I use "new Float(1L);" and cannot use "new Float("1L");" but "new Float(1.1F);" and "new Float("1.1F");" - works ok ?
And one more question about autoboxing/unboxing. Why "float float23 = 1L"; works ok and "Float float12 = "1L";" - not ?
Thanks.
Code example:
package com.oca;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
@Getter
@Setter
@ToString
class Floats {
Float float11 = 1.1f;
Float float12 = 1.1F;
float float21 = 1.1f;
float float22 = 1.1F;
float float23 = 1L;
Float float31 = new Float(1.1F);
Float float32 = new Float(1.1f);
Float float33 = new Float(1L);
Float float41 = new Float("1.1F");
Float float42 = new Float("1.1f");
}
public class Main {
public static void main(String[] args) {
Floats floats = new Floats();
System.out.println(floats);
}
}
Output:
Floats(float11=1.1, float12=1.1, float21=1.1, float22=1.1, float23=1.0, float31=1.1, float32=1.1, float33=1.0, float41=1.1, float42=1.1)
Read the documentation. Float(String) leads to Float.valueOf(String), which finally leads to Double.valueOf(String), describing what is accepted and what is not, it provides both textual description and an actual regular expression.
This is how it ends, allowing f, F, d and D only:
"[fFdD]?))" +
"[\\x00-\\x20]*");// Optional trailing "whitespace"
It also points out relevant section (3.10.2) of the langspec which (the langspec itself) is a suggested reading anyway, if you are interested in the details of the language.
For the assignment part: you can store integer types into floating point ones, that is why it works. 1L is not a text to parse in runtime, but a text evaluated to a number in compilation time, which can be stored in a float with automatic conversion. The same applies to Float(1L) as it becomes a floating point value (probably a double, but I do not know for sure) even before invoking the constructor (Float has float, double and String constructors only).
Boxing-unboxing is a funny beast, it does no automatic conversion at all, and thus input has to be a float already. Practically you can choose between
Float f1=(float)1L;
Float f2=new Float(1L);
if you absolutely want to get a Float from 1L.
If you open the Java 9 documentation of Float(String), it says
Deprecated. It is rarely appropriate to use this constructor. Use [...] valueOf(String) to convert a string to a Float object.
Which leads to
[...] To avoid calling this method on an invalid string and having a NumberFormatException be thrown, the documentation for Double.valueOf lists a regular expression which can be used to screen the input.
And link leads to exactly the same description in Java 9 docs, which I have linked for Java 7 (being Java 7 is visible both in the link, and on the page, and as I linked it from the internet, it does not really tell anything about what Java version "I am on"), containing exactly the same excerpt I have quoted here.
Ps: I have not written a word about the JDK source code, and neither have you in the original question. You asked about the why, not the how. In short: because it is specified this way.