Java8:double,float文本,后缀为小写和大写;类型构造函数和类型装箱/取消装箱

Java8:double,float文本,后缀为小写和大写;类型构造函数和类型装箱/取消装箱,java,java-8,primitive,Java,Java 8,Primitive,我看到float和double在不同的情况下有后缀。 那么,浮点数的后缀F和F,双打的后缀D和D有什么区别呢? 有这种行为的历史吗 还有关于类型构造函数的问题,例如float类型(double的行为相同): 为什么我可以使用“新浮点(1L)”,而不能使用“新浮点(1L)”,但“新浮点(1.1F)”和“新浮点(1.1F)”-可以吗 还有一个关于自动装箱/拆箱的问题。 为什么“浮动23=1L”;工作正常且“浮动12=“1L”;-不正常 谢谢 代码示例: package com.oca; impor

我看到float和double在不同的情况下有后缀。 那么,浮点数的后缀F和F,双打的后缀D和D有什么区别呢? 有这种行为的历史吗

还有关于类型构造函数的问题,例如float类型(double的行为相同): 为什么我可以使用“新浮点(1L)”,而不能使用“新浮点(1L)”,但“新浮点(1.1F)”和“新浮点(1.1F)”-可以吗

还有一个关于自动装箱/拆箱的问题。 为什么“浮动23=1L”;工作正常且“浮动12=“1L”;-不正常

谢谢

代码示例:

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);
    }
}
输出:

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)

Float构造函数需要Float、double或string值(有3个不同的构造函数)。您试图传递一个
long
,这意味着
long
将在调用构造函数之前转换为float

当您将值作为字符串传递(传递给需要字符串的构造函数)时,它希望您传递的是
浮点值
-而不是
长值
或其他任何值,这就是为什么您尝试调用时会得到
NumberFormatException
:例如
新浮点值(“1L”)


旁注:所有这3个构造函数都将在Java 9中生成弃用警告,并声明您应该使用
Float.valueOf()

阅读文档。Float(String)导致Float.valueOf(String),它最终导致,描述什么是可接受的,什么是不可接受的,它提供了文本描述和实际的正则表达式

这是它的结束方式,仅允许f、f、d和d:

"[fFdD]?))" +
"[\\x00-\\x20]*");// Optional trailing "whitespace"
它还指出了langspec的相关章节(3.10.2),如果您对语言的细节感兴趣,建议您阅读该章节(langspec本身)

对于赋值部分:可以将整数类型存储为浮点类型,这就是它工作的原因。1L不是要在运行时解析的文本,而是在编译时计算为一个数字的文本,可以通过自动转换存储在浮点中。这同样适用于Float(1L),因为它甚至在调用构造函数(Float只有Float、double和String构造函数)之前就变成了浮点值(可能是double,但我不确定)

装箱拆箱是一个有趣的怪兽,它根本不进行自动转换,因此输入必须是一个浮点数。实际上,你可以在两者之间做出选择

Float f1=(float)1L;
Float f2=new Float(1L);
如果你绝对想从1L得到一个浮动


编辑:如果你知道答案,请不要问

如果您打开的Java9文档,它会说

不赞成。使用此构造函数很少是合适的。使用[…]将字符串转换为浮点对象

这导致了

[…]为了避免对无效字符串调用此方法并引发NumberFormatException,的文档列出了可用于筛选输入的正则表达式

链接导致了Java 9文档中完全相同的描述,我为Java 7链接了这些文档(Java 7在链接中和页面上都是可见的,当我从internet链接它时,它实际上没有告诉任何关于Java版本“我在上”的内容),包含了我在这里引用的完全相同的摘录


Ps:关于JDK源代码,我一句话也没写过,你在最初的问题中也没写过。你问的是为什么,不是怎么问的。简而言之:因为它是这样指定的。

也许您使用的是较旧的Java版本:当我检查
Float(String)
constructor(在Java 8和Java 9上)时,我在同一个类中看到对
parseFloat()
的调用,调用:
FloatingDecimal.parseFloat()
调用
readJavaFormatString()
,后者返回的结果将转换为浮点值。