命令行参数中的转义序列 (Java)

Posted

技术标签:

【中文标题】命令行参数中的转义序列 (Java)【英文标题】:Escape sequences in command line arguments (Java) 【发布时间】:2019-10-05 07:10:59 【问题描述】:

根据How to use line break argument

当您在 Java 中将字符串定义为“Hello\nHello”时,它不包含“\” 特点。这是换行符的转义序列:“\n”只是 一个字符。

当你使用这个字符串作为你的参数时 然而,程序(所以字符串是在外面定义的),“\n”是 解释为两个字符:'\' 和 'n'。

为什么不编译包含转义序列的命令行参数?我以为命令行参数被放入数组 String[] args 中?

而 String[] args 将包含 args[0] = "Hello\nJava";

【问题讨论】:

【参考方案1】:

命令行参数不是 Java 源代码,因此 Java 源代码中字符含义的规则不适用。

命令行参数的解释或其他方式是命令解释器的工作; Java 没有被特殊对待。例如,在大多数(全部?)Linux shell 中,\n 不会被替换为带引号的字符串:

  $ echo 'a \n b'
  a \n b

在引号之外,反斜杠-n 表示“字面上的 n”,这与“n”相同,因为“n”对 shell 没有任何特殊意义。

 $ echo a\nb
 anb

当然,Java 系统可以在命令解释器之后应用自己的处理,但大多数 Linux 用户会觉得这很混乱;与其他命令相比,Java 命令的行为会不一致。

【讨论】:

so String[] args 存储了命令解释器处理的字符串 对。命令解释器根据自己的规则(此时在 shell 之间相当标准)将命令行分解为参数,并将它们传递给创建的进程。如果该进程正在运行 Java 虚拟机,那么 JVM 可能会将其中一些参数原样传递给 main() 函数;我不知道 JVM 规范是否要求这样做,但从经验上讲,Linux 上的 Oracle 实现确实如此。【参考方案2】:

转义序列不会被命令 shell 转换成它们对应的字符代码 (How can I echo a newline in a batch file?),所以你想知道为什么 java 程序在调用它时没有对接收到的参数进行一些按摩。好吧,原因很简单:按摩是任意,也许有些用户不希望字符串被解释为人类文本;但是一个字符串表示其他事物,其中转义代码的任意转换是失败的概括。一些例子:

    字符串是像c:\my\folder\number\n这样的windows文件路径,在那里你可以找到两个\n,如果java随意概括为人类文本将犯下重大错误。 文字ids,密码,ascii 艺术, 可序列化内容的结构化表示,例如 xml、模型对象、专有内容等。

现在,如果您定义要编译的字符串 INSIDE java 代码,编译后所有\? 将被编译成它们对应的转义码(作为语言的一个特性);但是您可以通过转义转义来告诉 java 编译器不要这样做,即\\?;但是这个编译问题。在运行时,所有字符串都只不过是char[],并且不会对其应用任意按摩。

Check the JLS:

如果转义中反斜杠后面的字符不是 ASCII b, t, n, f, r, ", ', \, 0, 1, 2, 3, 4, 5,则编译时错误、6 或 7。Unicode 转义符 \u 被较早处理(第 3.3 节)。

【讨论】:

以上是关于命令行参数中的转义序列 (Java)的主要内容,如果未能解决你的问题,请参考以下文章

如何转义变量中的特殊字符以在 bash 中提供命令行参数

如何阻止我的命令行参数在 Maven 插件中被转义?

如何在命令行启动参数上转义文件路径中的空格

如何在命令行启动参数上转义文件路径中的空格

转义 .NET 命令行参数的规范解决方案

在 Windows 脚本中读取命令行参数时,有没有办法转义逗号字符?