System.out.print() 如何工作?

2022-09-01 17:26:05

我已经使用Java很长一段时间了,我想知道这个函数是如何工作的。System.out.print()

这是我的疑问:

作为一个函数,它在io包中的某个地方有一个声明。但是Java开发人员是如何做到这一点的,因为这个函数可以接受任意数量的参数和任何参数类型,无论它们是如何排列的呢?例如:

System.out.print("Hello World");
System.out.print("My name is" + foo);
System.out.print("Sum of " + a + "and " + b + "is " + c);
System.out.print("Total USD is " + usd);

无论变量的数据类型是什么,或者它们是如何传递的,都不会抛出错误。a, b, c, usd, fooSystem.out.print()

对我来说,我从来没有参与过任何要求这样的项目。如果有的话,如果我得到这样的要求,我真的不知道如何解决它。

任何人都可以向我解释它是如何完成的吗?


答案 1

System.out只是 的一个实例。您可以检查其JavaDoc。其可变性基于方法重载(多个方法具有相同的名称,但具有不同的参数)。PrintStream

此打印流将其输出发送到所谓的标准输出


在你的问题中,你提到了一种称为可变参数函数(或变调函数)的技术。不幸的是,它不受 的支持,因此您一定将其误认为是其他内容。但是,在Java中实现这些非常容易。只需查看文档即可。PrintStream#print


如果你很好奇Java是如何知道如何连接非字符串变量的,它主要是Java编译器的责任。"foo" + 1 + true + myObj

当串联中不涉及任何变量时,编译器只需连接字符串。当涉及变量时,串联将转换为StringBuilder#append链。生成的字节码中没有串联指令;即运算符(当谈论字符串串联时)在编译期间被解析。+

Java中的所有类型都可以转换为字符串(通过类中的方法,通过类中的方法,通过它们自己的对象,...)。如果您有兴趣,可以检查StringBuilder的源代码。intIntegerbooleanBoolean#toString


更新:我自己很好奇,并检查了(使用javap)我的例子编译成什么。结果:System.out.println("foo" + 1 + true + myObj)

System.out.println(new StringBuilder("foo1true").append(myObj).toString());

答案 2

即使它看起来好像需要可变数量的参数,它也没有。如果仔细观察,字符串只是串联的,您可以对任何字符串执行相同的操作。唯一发生的事情是,您正在传入的对象通过java调用该方法隐式转换为字符串。System.put.print...()toString()

如果您尝试执行此操作,它将失败:

int i = 0;
String s = i;
System.out.println(s);

原因是,因为这里隐式转换没有完成。

但是,如果将其更改为

int i = 0;
String s = "" + i;
System.out.println(s);

它有效,这也是使用时发生的情况。System.put.print...()

如果你想在java中实现可变数量的参数来模仿类似C的东西,你可以这样声明它:printf

public void t(String s, String ... args)
{
    String val = args[1];
}

这里发生的事情是传入一个字符串数组,其中包含所提供参数的长度。在这里,Java可以为您进行类型检查。

如果你想要一个真正的printf,那么你必须这样做:

public void t(String s, Object ... args)
{
    String val = args[1].toString();
}

然后,您是否必须相应地投射或解释参数。


推荐