具有4个以上十六进制数字的Java unicode转义

时间:2016-06-07 12:44:43

标签: java ant

Ant <propertyfile>任务生成的Java属性文件包含匈牙利字母\u000151的unicode转义ő

我期待\u0151,这是Ant中的一个错误吗? (Ant 1.8.0,Java 1.7.0)

(根据JLS,只有4位数的unicode转义被视为有效...)

2 个答案:

答案 0 :(得分:1)

开始阅读Unicode序列的好地方是类字符的Javadoc:https://docs.oracle.com/javase/8/docs/api/java/lang/Character.html。我不能确定这是否是一个bug,但它看起来像一个bug。您也可以使用将任何文本转换为unicode序列的实用程序,反之亦然,以解决此问题。您可以在此article中找到具有此类实用程序的开源库的链接。查找文章“ String Unicode converter

中的段落

答案 1 :(得分:0)

虽然我没有发现与此问题相关的错误报告,但它可能是一个基于官方Oracle文档的错误:Supplementary Characters in the Java Platform

本文档指出一个补充字符可由两个 unicode转义表示:

  

对于使用的字符编码不能代表的情况   直接使用字符,Java编程语言提供了Unicode   转义语法。此语法尚未增强以表达   补充字符直接。相反,他们代表   两个代码单元中的两个连续Unicode转义   UTF-16表示的字符。例如,角色   U + 20000写成&#34; \ uD840 \ uDC00&#34;。

本文档还指定了表示文本输入 unicode转义语法的语法(即Java在语言级别不支持它):

  

对于文本输入,Java 2 SDK提供了代码点输入方法   它接受形式为&#34; \ Uxxxxxx&#34;的字符串,其中大写&#34; U&#34;   表示转义序列包含六个十六进制数字,   从而允许补充字符。小写&#34; u&#34;指示   转义序列的原始形式,&#34; \ uxxxx&#34;。

这意味着Ant <propertyfile>任务不正确,它应该生成\u0151\U000151而不是\u000151(请注意大写/小写U) - 至少基于在上面的文档。

但实际上,\ Uxxxxxx语法似乎不受支持:

[test.properties]

key1=\u0151
key2=\u000151
key3=\U000151

[PropertiesParserTest.java]

import static org.junit.Assert.assertEquals;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Properties;
import org.junit.Test;

public class PropertiesParserTest {
    @Test
    public void testLoad() throws IOException {
        try (InputStream input = getClass().getResourceAsStream("test.properties")) {
            Properties p = new Properties();
            p.load(input);

            // Valid unicode escape
            assertEquals("ő", p.getProperty("key1"));

            // The 6-digit unicode escape generated by Ant is incorrect
            assertEquals("\u0001" + "51", p.getProperty("key2"));

            // \Uxxxxxx is not supported
            assertEquals("U000151", p.getProperty("key3"));
        }
    }

    @Test
    public void testGenerate() throws IOException {
        Properties p1 = new Properties();
        p1.setProperty("key1", "ő");
        p1.setProperty("key2", "\u000151");
        // Not supported in practice: p.setProperty("key3", "\U000151");

        File file = File.createTempFile("PropertiesParserTest_", ".properties");
        System.out.println(file);

        try (OutputStream output = new FileOutputStream(file)) {
            p1.store(output, null);
        }

        try (InputStream input = new FileInputStream(file)) {
            Properties p2 = new Properties();
            p2.load(input);

            // Valid unicode escape
            assertEquals("ő", p2.getProperty("key1"));

            // The 6-digit unicode escape generated by Ant is incorrect
            assertEquals("\u0001" + "51", p2.getProperty("key2"));
        }
    }
}