为什么 KeyEvent getCharacter 返回字符串而不是字符

Why KeyEvent getCharacter returns a string not a character

提问人:Osama El-Ghonimy 提问时间:5/13/2023 更新时间:5/13/2023 访问量:87

问:

根据我的理解,应该返回一个类型的方法。getCharacter()KeyEventchar

例如,如果我必须检查键入的键是否为数字,我可以只使用 not .Character.isDigit(e.getCharacter())Character.isDigit(e.getCharacter().charAt(0))

我还通过打印它总是返回来检查返回字符串的长度。此字符串的任何解释或其他用法?e.getCharacter().length()1

Java JavaFX KeyEvent 事件驱动

评论

7赞 Turing85 5/13/2023
你读过文档吗?Java 中的---都是 UTF-16 编码的。Unicode 字符可能大于单个 UTF-16 ,因此它们“不适合”。charchar
1赞 Turing85 5/13/2023
"...其中每个字符由一个或两个 16 位元素组成。
1赞 Slaw 5/13/2023
关键是,这是一个 16 位数字,不足以表示世界上所有有效的字符。正如文档所述:“与键类型化事件关联的 Unicode 字符或字符序列。如果密钥从基本多语言平面外部生成单个 Unicode 字符,该字符需要由 Java 中的相应代理项对编码,或者密钥本身生成多个 Unicode 字符,则包含多个元素”。char
1赞 James_D 5/13/2023
如果要为文本字段上的关键事件注册事件处理程序,则几乎可以肯定,无论如何都做错了事情。
2赞 Slaw 5/13/2023
"所以,当我输入一个数字时,它被转换了,而不是当我按下一个按钮时“——如果你试图将文本动态地转换为一个数字,那么这应该通过一个 .如果您尝试动态获取文本字段文本的“长度”,那么您应该执行类似 的操作,这将返回一个 .例如,您可以通过执行 .TextFormatteraTextField.textProperty().length()IntegerBindingaLabel.textProperty().bind(aTextField.textProperty().length().asString())

答:

7赞 Basil Bourque 5/13/2023 #1

KeyEvent#getCharacter()返回String

根据我的理解,KeyEvent 的 getCharacter() 方法应该返回一个 char 类型。

你从哪里得到这种理解?javafx.scene.input.KeyEvent#getCharacter() 的 Javadoc 表示该方法返回 String 对象引用,而不是原语。char

避免char

要知道,这是一个遗留类型,从 Java 2 开始基本上就被破坏了,从 Java 5 开始就被遗留了。作为 16 位值,a 在物理上无法表示 Unicode 中定义的 149,186 个字符中的大多数。charchar

代码点

请改用代码点整数来处理单个字符。

int[] codePoints = myKeyEvent.getCharacter().codePoints().toArray() ;

然后,您可以询问这些代码点中的任何一个是否表示数字

boolean isDigit = Character.isDigit( myCodePoint ) ;

示例代码

String input = "A1😷";  // FACE WITH MEDICAL MASK  is hex 1F637, decimal 128,567.

System.out.println( "input.length(): " + input.length() ) ;  
System.out.println( "Count code points: " + input.codePoints().count() + "\n" ) ;
  
input.codePoints ( ).forEach (
        ( int codePoint ) ->
        {
            System.out.println (
                    "Code point: " + codePoint +
                            " | name: " + Character.getName ( codePoint ) +
                            " | digit: " + Character.isDigit ( codePoint ) +
                            " | = " + Character.toString ( codePoint ) +
                            "\n- - - - - - - - - - - - - - - - - - - - "
            );
        }
);

请参阅在 Ideone.com 运行的此代码

input.length(): 4
Count code points: 3

Code point: 65 | name: LATIN CAPITAL LETTER A | digit: false | = A
- - - - - - - - - - - - - - - - - - - - 
Code point: 49 | name: DIGIT ONE | digit: true | = 1
- - - - - - - - - - - - - - - - - - - - 
Code point: 128567 | name: FACE WITH MEDICAL MASK | digit: false | = 😷
- - - - - - - - - - - - - - - - - - - - 

你说:

我可以只使用Character.isDigit(e.getCharacter())

不可以。该方法采用传统或现代代码点。该方法不返回任何一个;如上所述,该方法返回 a。isDigitcharintgetCharacterString


有关背景信息,请参阅Joel Spolsky撰写的令人惊讶的有趣文章:The Absolute Minimum Every Software Developer Absolutely, Positive Must Know About Unicode and Characters Sets (No Excuses!)

评论

1赞 Slaw 5/13/2023
这个答案很好地解决了这个问题。我只想指出,OP 从未想过返回 a,而是在问为什么返回 a 而是返回 .他们不了解,或者根本不知道“代孕对”。当他们说他们可以使用时,他们希望这是可能的,因为不必打电话会更好(他们为什么“应该”返回而不是这样做的部分理由;再次,不了解代理对)。KeyEvent#getCharacter()charcharStringCharacter.isDigit(e.getCharacter())charAt(0)charString
0赞 Basil Bourque 5/13/2023
@Slaw 问题明确地、反复地说,他们期望一个.我认为强调仔细阅读 Javadoc 而不是凭直觉编程是很重要的。当然,他们不了解 Java 的细微差别,这对任何新手来说都是一个令人困惑的话题。charcharString
1赞 Slaw 5/13/2023
是的,但这是语言障碍。英语显然(在我看来)不是他们的第一语言。他们使用的词语和意思是不同的。
0赞 James_D 5/14/2023
我认为这个答案很好,在网站的一般背景下,因为其他有实际问题的用户将从这个答案中受益。这对 OP 可能没有帮助,甚至有些无用,因为他们正在发布一个 XY 问题,这可能会鼓励他们继续对他们试图解决的实际问题提出错误的解决方案。