Is there a method in Java that mimics the cast of primitive type to Character?

194 Views Asked by At

To simplify some bytecode analysis, I want to replace explicit (down)casts of primitive types in a Java program by calls to the equivalent method of the boxed type. In most cases it's simple:

double d = 42.0;
int i = (int)d;

Can be turned into

Double tmp = new Double(d);
int i = tmp.intValue();

This works for all signed types. But there is not such methods for char and Character. That is, Integer, Float, etc have the methods intValue, floatValue, etc. but none has a method charValue. Is there a jdk method to go from primitive type to char/Character?

So basically, is there something like this:

Integer num = new Integer(65);
char ch = num.charValue();

And the key is to not use (char).

2

There are 2 best solutions below

2
On BEST ANSWER

If you're modifying bytecode, I think you do not need to cast to char. In the bytecode, the char type is a second-class citizen actually handled as an int. From JVMS §4.9.2:

An instruction operating on values of type int is also permitted to operate on values of type boolean, byte, char, and short.

As noted in §2.3.4 and §2.11.1, the Java Virtual Machine internally converts values of types boolean, byte, short, and char to type int.)

So while you can't, say, assign an int to a char in the Java language without an explicit cast, you can do that in the bytecode, since they have the same "verification type", which is int. The bytecode representation of a char is just an int that happens to have its upper two bytes zero. So instead of:

char ch = num.charValue();

You would be able to get away with (in bytecode):

int ch = num.intValue() & 0x0000FFFF;

And then just pretend that ch is a char (e.g., pass it to methods that expect a char or store it in a char field or array).

However, if I understand it correctly, that's what the i2c int to char cast instruction already does, so replacing it by an explicit AND operation is not going to be any simpler.

It's also surprisingly hard to find what actually happens if you cast a (signed)double into an (unsigned)char.

When you cast from float or double to byte, short, or char, it first casts to int, which saturates out-of-range values to Integer.MAX_VALUE or Integer.MIN_VALUE, and then truncates the bytes of the int to fit the final type. See JLS §5.1.3 – Narrowing Primitive Conversion. The truncation step means that conversion of out-of-range floating-point values to byte, short, or char is probably not going to give a useful result.

3
On

I don't think that there is any direct method in the classes to get a char representation. However, the simple solution is:

Integer num = new Integer(65);
char ch = (char)num.intValue();

I am sure that you thought of this. But there doesn't seem to be a better way.