How to generate an UnmappableCharacterException fr

2020-07-19 04:54发布

[Note: question basically re-edited after a lot of playing around]

In Java, you have Charset, defining a character encoding. From a Charset, you can obtain two objects:

  • a CharsetEncoder, to turn a char sequence into a byte sequence;
  • a CharsetDecoder, to turn a byte sequence into a char sequence.

Both of these classes have the following methods defined: .onUnmappableCharacter() and .onMalformedInput(). If you tell them for each of these to CodingErrorAction.REPORT they will throw either of these two exceptions: UnmappableCharacterException and MalformedInputException.

With a CharsetEncoder, I am able to generate both of them:

  • feed it with a CharBuffer containing two high surrogates following one another --> MalformedInputException;
  • feed it with a CharBuffer containing a char (or char sequence) which the encoding cannot represent: UnmappableCharacterException.

With a CharsetDecoder:

  • feed it with an illegal byte sequence: MalformedInputException -- easy to do;
  • UnmappableCharacterException --> how?

In spite of all my research, I just couldn't do it.

All of this in spite of having played a lot with CharsetDecoder. I could find no combination of Charset and byte sequence able to generare this error...

Is there any at all?

2条回答
够拽才男人
2楼-- · 2020-07-19 05:32

When you supply a character to the decoder, the decoder can tell that a character is not appropriate for the charset and throw a UnmappableCharacterException.

When you supply a byte array to the encoder, is assumes that it has been encoded properly. Thus when it decodes your byte array and gets a bad character, it assumes you have a broken encoder or bad input, which causes a MalformedInputException.

查看更多
手持菜刀,她持情操
3楼-- · 2020-07-19 05:35

It's just a matter of finding a character set with an unmappable byte sequence.

Take, for example, IBM1098. It can't map the hex bytes

0x80
0x81

So put these in a ByteBuffer, rewind it, and try to decode it.

public class Test {
    public static void main(String[] args) throws CharacterCodingException {
        ByteBuffer buffer = ByteBuffer.allocate(8);
        buffer.putInt(0x80);
        buffer.putInt(0x81);
        buffer.position(0);
        Charset charset = Charset.forName("IBM1098");
        CharsetDecoder decoder = charset.newDecoder();
        decoder.decode(buffer);
    }   
}

This throws

Exception in thread "main" java.nio.charset.UnmappableCharacterException: Input length = 1
    at java.nio.charset.CoderResult.throwException(CoderResult.java:282)
    at java.nio.charset.CharsetDecoder.decode(CharsetDecoder.java:816)
    at com.test.Test.main(Test.java:16)

Ideone.com attempt.

查看更多
登录 后发表回答